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

如何用TypeScript泛型实现参数类型的相互依赖?

解决方案

不用提前提取类型,同时让第二个对象参数的键严格受第一个数组参数的字面量值约束,你可以这样写:

declare function test<T extends readonly string[]>(a: readonly [...T], b?: Record<T[number], string>): unknown;

// 测试验证
test(['a', 'b'], {
  a: 'someValue',
  b: 'someOtherValue',
  c: 'thisShouldNotWork' // 此处会触发TypeScript错误,符合预期
});

为什么原写法无效?

你最初的代码里,TypeScript默认把['a', 'b']推断成了string[],而不是包含具体字面量的元组。这导致T[number]被解析为宽泛的string类型,Record<string, string>自然无法限制对象的键,所以c: 'thisShouldNotWork'不会报错。

方案原理

用readonly [...T]作为第一个参数的类型,会引导TypeScript将传入的数组推断为只读字面量元组。此时T[number]会被解析为数组元素的字面量联合类型(也就是'a' | 'b'),Record<T[number], string>就能正确约束第二个对象的键只能是数组中存在的字面量值。

另一种可选写法(需加as const)

如果不介意在调用时给数组加as const断言,也可以简化函数声明,同样能达到效果:

declare function test<T extends readonly string[]>(a: T, b?: Record<T[number], string>): unknown;

test(['a', 'b'] as const, {
  a: 'someValue',
  b: 'someOtherValue',
  c: 'thisShouldNotWork' // 此处触发错误
});

as const会强制TypeScript把数组推断为只读字面量元组,同样避免了提前提取类型的步骤。

内容的提问来源于stack exchange,提问作者vinvin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:02:21