我有以下PAGES
,我想为每个函数创建帮助程序函数以解析每个路径。这意味着将部分替换为":"。
帮助程序函数需要具有严格的类型,具体取决于需要解析的参数。
有没有办法在下面的代码中添加一个type
,只允许所选函数需要的参数?更换any
任何帮助将不胜感激。
const PAGES = {
TEST: 'YO/:id/again/:param', // params 'id' and 'param' required.
TEST2: 'YO2/:hello/:yo' // params 'hello' and 'yo' required.
} as const
type ValidParams = any; //replace 'any' and allow only valid params.
type HelperFunctions<T> = { [K in keyof T]: ( params: ValidParams ) => string }
const createHelperFunctions = <P extends Record<string, string>( pages: P ): HelperFunctions<P> => {
const pageMap = { ...pages };
const helpers: Record<any, any> = {};
(Object.keys(pageMap) as (keyof P)[]).forEach((key) => {
// only accept valid params.
helpers[key] = ( params: ValidParams ) => {
const route = routeMap[key];
return '' // will call another function to replace params in the route.
}
})
return helpers as ReturnType<typeof createHelperFunctions<P>>;
}
const helpers = createHelperFunctions( PAGES );
// no errors and return 'YO/value-1/again/value-2'
helpers.TEST({ id: 'value-1', param: 'value-2' });
// no errors and return 'YO2/value-2/value-1'
helpers.TEST2({ yo: 'value-1', hello: 'value-2' });
// should get type error
helpers.TEST({ yo: 'value' });
// should get type error
helpers.TEST({ yo: 'value', hello: 'value' });
// should get type error
helpers.TEST({ yo: 'value', hello: 'value', id: 'value', param: 'value' });
// should get type error
helpers.TEST({});
让我们从ValidParams
类型开始。给定一个字符串文字P
,它应该生成一个包含P
所有参数的对象类型。我们可以使用模板文字类型来实现这一点。
type ValidParams<P extends string> =
P extends `${string}:${infer U}/${infer R}`
? Record<U, string> & ValidParams<R>
: P extends `${string}:${infer U}`
? Record<U, string>
: {}
此类型现在可以在HelperFunctions
中使用,如下所示:
type HelperFunctions<T extends Record<string, string>> = {
[K in keyof T]: (params: ValidParams<T[K]>) => string
}
这将为您提供TEST
方法的严格类型。
操场
我不确定您是否希望返回类型也严格类型为字符串文字。但无论如何,这是那个怪物:
操场