TypeScript定义嵌套键泛型函数时第二个参数推导为never问题
问题原因
你当前的类型定义把K、V两个泛型参数声明在了外层类型上,会在类型初始化时就完成默认值推导,无法在函数调用时根据传入的第一个参数动态收窄第二个参数的类型。
当K取默认值keyof T(即所有顶层键的联合类型)时,T[K]代表所有内层对象的联合类型,而对联合类型取keyof时,TypeScript会返回所有联合成员共有的键(即各成员键的交集)。你的测试对象中四个内层对象的键集合没有公共成员,交集为空,因此第二个参数的类型被推导为never。
正确实现
把和入参相关的泛型参数移动到函数签名上,让TypeScript在函数调用时,根据实际传入的第一个参数动态推导第二个参数的允许值范围:
// 泛型函数类型定义 type Test<T extends Record<string, Record<string, any>>> = <K extends keyof T>(key: K, key2: keyof T[K]) => void // 基于convertFunctionsMap使用该类型 const convert: Test<typeof convertFunctionsMap> = (key, key2) => { // 此处可以获得完整的类型提示 const targetFn = convertFunctionsMap[key][key2] } // 调用时会获得正确的类型校验 convert('ms', 'h') // 校验通过 convert('ms', 'ms') // 类型报错,ms对应的内层对象不存在ms键
如果需要获得更精确的返回值类型,可以给第二个参数也增加泛型约束:
type StrictTest<T extends Record<string, Record<string, any>>> = <K extends keyof T, V extends keyof T[K]>(key: K, key2: V) => T[K][V]
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

