Simplify createRouteRef type signature

Replace dual TParams/TParamKeys type parameters with a single TParamKey,
removing unnecessary complexity while preserving runtime behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
This commit is contained in:
Fredrik Adelöw
2026-03-28 10:58:37 +01:00
parent 40c8ec9615
commit 49397c16e0
5 changed files with 21 additions and 29 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-compat-api': patch
---
Removed unnecessary type argument from internal `createRouteRef` call.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/frontend-plugin-api': minor
---
Simplified the type signature of `createRouteRef` by replacing the dual `TParams`/`TParamKeys` type parameters with a single `TParamKey` parameter. This is a breaking change for callers that explicitly provided type arguments, but most usage that relies on inference is unaffected.
@@ -220,7 +220,7 @@ function convertOldToNew(
const legacyRef = ref as LegacyRouteRef;
const legacyRefStr = String(legacyRef);
const newRef = OpaqueRouteRef.toInternal(
createRouteRef<{ [key in string]: string }>({
createRouteRef({
params: legacyRef.params as string[],
}),
);
+4 -15
View File
@@ -814,25 +814,14 @@ export interface CreateFrontendPluginOptions<
}
// @public
export function createRouteRef<
TParams extends
| {
[param in TParamKeys]: string;
}
| undefined = undefined,
TParamKeys extends string = string,
>(config?: {
readonly params?: string extends TParamKeys
? (keyof TParams)[]
: TParamKeys[];
export function createRouteRef<TParamKey extends string = never>(config?: {
readonly params?: TParamKey[];
aliasFor?: string;
}): RouteRef<
keyof TParams extends never
[TParamKey] extends [never]
? undefined
: string extends TParamKeys
? TParams
: {
[param in TParamKeys]: string;
[param in TParamKey]: string;
}
>;
@@ -41,23 +41,16 @@ export interface RouteRef<
* @public
*/
export function createRouteRef<
// Params is the type that we care about and the one to be embedded in the route ref.
// For example, given the params ['name', 'kind'], Params will be {name: string, kind: string}
TParams extends { [param in TParamKeys]: string } | undefined = undefined,
TParamKeys extends string = string,
// ParamKey is narrowed to the literal union of param name strings.
// Defaulting to never means we get undefined params when the array is empty or omitted.
TParamKey extends string = never,
>(config?: {
/** A list of parameter names that the path that this route ref is bound to must contain */
readonly params?: string extends TParamKeys
? (keyof TParams)[]
: TParamKeys[];
readonly params?: TParamKey[];
aliasFor?: string;
}): RouteRef<
keyof TParams extends never
? undefined
: string extends TParamKeys
? TParams
: { [param in TParamKeys]: string }
[TParamKey] extends [never] ? undefined : { [param in TParamKey]: string }
> {
const params = (config?.params ?? []) as string[];
const creationSite = describeParentCallSite();
@@ -65,7 +58,7 @@ export function createRouteRef<
let id: string | undefined = undefined;
return OpaqueRouteRef.createInstance('v1', {
T: undefined as unknown as TParams,
T: undefined as any,
getParams() {
return params;
},