diff --git a/packages/core-plugin-api/report.api.md b/packages/core-plugin-api/report.api.md index 06333c1fb4..ab31693b1e 100644 --- a/packages/core-plugin-api/report.api.md +++ b/packages/core-plugin-api/report.api.md @@ -613,9 +613,13 @@ export type OptionalParams< > = Params[keyof Params] extends never ? undefined : Params; // @public @deprecated -export type ParamKeys = keyof Params extends never +export type ParamKeys = [AnyRouteRefParams] extends [ + Params, +] + ? string[] + : keyof Params extends never ? [] - : (keyof Params)[]; + : Array; // @public @deprecated export type ParamNames = diff --git a/packages/core-plugin-api/src/routing/ExternalRouteRef.test.ts b/packages/core-plugin-api/src/routing/ExternalRouteRef.test.ts index f6e072f760..05e7a23d5d 100644 --- a/packages/core-plugin-api/src/routing/ExternalRouteRef.test.ts +++ b/packages/core-plugin-api/src/routing/ExternalRouteRef.test.ts @@ -87,7 +87,7 @@ describe('ExternalRouteRef', () => { const _3 = createExternalRouteRef({ id: '3', params: ['x', 'y'] }); // @ts-expect-error validateType<{ x: string }, any>(_3); - // extra z, we validate this at runtime instead + // @ts-expect-error validateType<{ x: string; y: string; z: string }, any>(_3); validateType<{ x: string; y: string }, false>(_3); diff --git a/packages/core-plugin-api/src/routing/RouteRef.test.ts b/packages/core-plugin-api/src/routing/RouteRef.test.ts index 5314957a25..58013261ab 100644 --- a/packages/core-plugin-api/src/routing/RouteRef.test.ts +++ b/packages/core-plugin-api/src/routing/RouteRef.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { AnyParams, RouteRef } from './types'; +import { AnyParams, RouteRef, ParamKeys } from './types'; import { createRouteRef } from './RouteRef'; describe('RouteRef', () => { @@ -54,7 +54,7 @@ describe('RouteRef', () => { validateType(_2); // @ts-expect-error validateType<{ x: string; z: string }>(_2); - // extra z, we validate this at runtime instead + // @ts-expect-error validateType<{ x: string; y: string; z: string }>(_2); validateType<{ x: string; y: string }>(_2); @@ -71,4 +71,30 @@ describe('RouteRef', () => { // To avoid complains about missing expectations and unused vars expect([_1, _2, _3, _4].join('')).toEqual(expect.any(String)); }); + + it('should properly infer param keys', () => { + function validateType(_test: T) {} + + validateType>(['x', 'y']); + + // @ts-expect-error + validateType>(['asd']); + validateType>([]); + + // @ts-expect-error + validateType>([1]); + validateType>(['migrationId']); + + // @ts-expect-error + validateType>([1]); + validateType>([ + 'migrationId', + ]); + + // @ts-expect-error + validateType>(['asd']); + validateType>([]); + + expect(true).toBeDefined(); + }); }); diff --git a/packages/core-plugin-api/src/routing/SubRouteRef.test.ts b/packages/core-plugin-api/src/routing/SubRouteRef.test.ts index cec00de025..1db429e178 100644 --- a/packages/core-plugin-api/src/routing/SubRouteRef.test.ts +++ b/packages/core-plugin-api/src/routing/SubRouteRef.test.ts @@ -102,7 +102,7 @@ describe('SubRouteRef', () => { validateType<{ x: string; z: string }>(_2); // @ts-expect-error validateType<{ y: string }>(_2); - // extra z, we validate this at runtime instead + // @ts-expect-error validateType<{ x: string; y: string; z: string }>(_2); validateType<{ x: string; y: string }>(_2); diff --git a/packages/core-plugin-api/src/routing/types.ts b/packages/core-plugin-api/src/routing/types.ts index 32f26f19c1..4598574afb 100644 --- a/packages/core-plugin-api/src/routing/types.ts +++ b/packages/core-plugin-api/src/routing/types.ts @@ -35,9 +35,13 @@ export type AnyParams = AnyRouteRefParams; * @public * @deprecated this type is deprecated and will be removed in the future */ -export type ParamKeys = keyof Params extends never +export type ParamKeys = [AnyRouteRefParams] extends [ + Params, +] + ? string[] + : keyof Params extends never ? [] - : (keyof Params)[]; + : Array; /** * Optional route params.