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

TypeScript多参数泛型函数如何从指定参数推导类型

解决方案

你可以通过降低第二个参数的泛型推导优先级实现需求,TypeScript 4.7及以上版本内置了NoInfer工具类型,用来标记某个位置的泛型参数不参与类型推导,仅做后续类型校验:

type TypeA<T extends string> = Record<T, unknown>;
type TypeB<T> = { array: T[] };

// 仅修改泛型T在第二个参数的引用,包裹NoInfer
function fn<T extends string>(a: TypeA<T>, b: TypeB<NoInfer<T>>): void {}

如果使用的是4.7以下版本的TypeScript,可以自行实现NoInfer类型:

// 自定义NoInfer实现
type NoInfer<T> = [T][T extends any ? 0 : never];

type TypeA<T extends string> = Record<T, unknown>;
type TypeB<T> = { array: T[] };

function fn<T extends string>(a: TypeA<T>, b: TypeB<NoInfer<T>>): void {}

原理说明

默认情况下TypeScript会从泛型参数出现的所有位置共同推导类型,你的原始写法中第二个参数的array: ["attr1"]更早收窄了T的类型为"attr1",导致第一个参数的attr2属性不符合类型校验。
给第二个参数的T包裹NoInfer后,TypeScript会优先从第一个参数推导T的类型为所有对象键的联合类型"attr1" | "attr2",再用推导完成的T去校验第二个参数的数组元素是否属于T的子集,既符合你的推导预期,也能正常校验第二个参数的数组元素合法性。

修改后你原来的调用代码不会再抛出错误,如果你在第二个参数的数组中填写第一个参数不存在的键,TypeScript仍然会正常提示类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:57:04