在 TypeScript 中,当我将对象的键从
key
重新映射到 useKey
并将值更改为函数时,如何使用我赋予 another 函数的一些泛型类型,以便最终结果具有完整的类型安全性:
Playground Link(将鼠标悬停在钩子类型上并忽略 JS 错误)
const { useMyAwesomeResource } = handleResources({
resources: {
// TProps: TItem:
myAwesomeResource: handleResource<string, AwesomeResource>({
// do whatever
})
}
})
最后的结果应该如下所示(它使用
TProps
作为第一个参数,使用 TItem
作为结果):
useMyAwesomeResource: (resourceId: string) => AwesomeResource
代码:
// func result:
type HookResult<TItem> = {
data: TItem
}
type HookFunc<TItem, TProps> = (props: TProps) => HookResult<TItem>
type HookFuncs<TResourceHandlers> = {
[Key in keyof TResourceHandlers as `use${Capitalize<
string & Key
>}`]: HookFunc<TResourceHandlers[Key]> // <--- how do I access generic types
}
// config you need to pass to the func:
type ResourceHandler<TRawItem, TItem> = {}
interface Config {
resources: {
[resourceName: string]: ResourceHandler<any, any>
}
}
export const handleResources = (
config: Config
): HookFuncs<typeof config.resources> => {
// do whatever
})
// define the generic types:
const handleResource = <TItem, TProps = {}>(
resourceConfig: ResourceConfig<TItem, TProps>
): ResourceInfo<TItem, TProps> => resourceConfig
我觉得我缺少了这个拼图的一块。我知道这是可能的,因为我使用的 Redux RTK 库已经实现了这一点。
TypeScript 可以“推断”类型:
export type HookFuncs<TResourceHandlers> = {
[Key in keyof TResourceHandlers as `use${Capitalize<
string & Key
>}`]: TResourceHandlers[Key] extends BaseResourceConfig<
infer TItem,
infer TProps
>
? (opts: TProps & DefaultHookProps) => HookResult<TItem>
: never
}
现在 TypeScript 可以自动获取您的类型,并通过这个类型链了解所有类型。