bug: fixing issue with type inference for ParamKeys

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
blam
2024-10-14 16:26:09 +02:00
parent f1355742ed
commit f63ea9a583
5 changed files with 42 additions and 8 deletions
+6 -2
View File
@@ -613,9 +613,13 @@ export type OptionalParams<
> = Params[keyof Params] extends never ? undefined : Params;
// @public @deprecated
export type ParamKeys<Params extends AnyParams> = keyof Params extends never
export type ParamKeys<Params extends AnyParams> = [AnyRouteRefParams] extends [
Params,
]
? string[]
: keyof Params extends never
? []
: (keyof Params)[];
: Array<keyof Params>;
// @public @deprecated
export type ParamNames<S extends string> =
@@ -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);
@@ -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<undefined>(_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<T>(_test: T) {}
validateType<ParamKeys<{ x: string; y: string }>>(['x', 'y']);
// @ts-expect-error
validateType<ParamKeys<{}>>(['asd']);
validateType<ParamKeys<{}>>([]);
// @ts-expect-error
validateType<ParamKeys<{ [key in string]: string }>>([1]);
validateType<ParamKeys<{ [key in string]: string }>>(['migrationId']);
// @ts-expect-error
validateType<ParamKeys<{ [key in string]: string } | undefined>>([1]);
validateType<ParamKeys<{ [key in string]: string } | undefined>>([
'migrationId',
]);
// @ts-expect-error
validateType<ParamKeys<undefined>>(['asd']);
validateType<ParamKeys<undefined>>([]);
expect(true).toBeDefined();
});
});
@@ -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);
@@ -35,9 +35,13 @@ export type AnyParams = AnyRouteRefParams;
* @public
* @deprecated this type is deprecated and will be removed in the future
*/
export type ParamKeys<Params extends AnyParams> = keyof Params extends never
export type ParamKeys<Params extends AnyParams> = [AnyRouteRefParams] extends [
Params,
]
? string[]
: keyof Params extends never
? []
: (keyof Params)[];
: Array<keyof Params>;
/**
* Optional route params.