如何避免TypeScript映射类型中函数复杂推断导致的any值
解决方案
1. 用双重约束+Exact类型实现精确键校验
问题出在TS对返回函数的类型推断逻辑——它会自动扩展泛型范围来匹配额外属性。我们可以用NoInfer固定attributes的类型,再用Exact类型禁止initialValues出现额外键:
先定义辅助类型和更严格的Data类型:
// 辅助类型:拒绝包含额外键的对象 type Exact<T, U> = T extends U ? Exclude<keyof U, keyof T> extends never ? T : never : never type StrictData<T extends string> = { readonly attributes?: readonly T[] readonly initialValues?: Exact<Partial<Record<T, string>>, { [k: string]: string | undefined }> }
然后修改函数,用NoInfer强制TS先推断attributes的类型,再约束initialValues:
function dataFunc<T extends string>( data: () => StrictData<NoInfer<T>> ): () => StrictData<T> { return data }
现在再传age这种额外键,TS会直接报错,完美实现精确校验。
2. 避免any类型的小技巧
上面的StrictData已经把initialValues的类型锁死在Partial<Record<T, string>>,再加上Exact约束,所有键的值类型只能是string | undefined,不可能出现any。如果不小心写了不符合类型的值,TS会立刻提示。
3. 快速解决:用const断言缩小类型范围
如果不想改接口,最简单的方式是给attributes加as const,强制TS推断精确的字符串字面量类型,而不是宽泛的string:
const notOkay = dataFunc(() => ({ attributes: ['firstName'] as const, initialValues: { firstName: 'value', age: 2 // 这里会报错 }, }))
这种方式直接缩小了attributes的类型范围,让TS能正确约束initialValues的键。
内容的提问来源于stack exchange,提问作者ShayDavidson
相关产品推荐
相关产品推荐

