You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:14:49