TypeScript如何从函数参数推断泛型参数A,无需手动传入?
TypeScript泛型推断优化问题
原代码示例
function runOnlyGivenActions<T extends object, A extends keyof T>(actions: readonly A[]) { // 处理actions逻辑 console.log(actions); type T2 = Pick<T, A>; } interface Foo { hello(): string answer(): number; dontSelectMe(): void; } // 当前调用方式:需要手动传入第二个泛型参数 runOnlyGivenActions<Foo, "hello" | "answer">(["hello", "answer"])
背景说明
泛型参数A是T的成员筛选器,用来构建Pick<T,A>这类新类型。
runOnlyGivenActions函数不需要接收T的具体实例,只依赖T的类型契约。实际场景中,它会通过await import动态加载Node.js模块,获取实现T的具体类。
问题
能不能不用手动传入"hello" | "answer"作为第二个泛型参数,让TypeScript直接从传入的数组参数里自动推断出A的类型?理想调用方式是:
runOnlyGivenActions<Foo>(["hello", "answer"])
解决方案
可以通过调整泛型参数的约束和默认值实现自动推断,两种常用写法如下:
写法一:通过数组元素类型推导
function runOnlyGivenActions<T extends object>(actions: readonly (keyof T)[]) { // 处理actions逻辑 console.log(actions); // 从数组元素类型推导筛选后的类型 type T2 = Pick<T, typeof actions[number]>; } interface Foo { hello(): string answer(): number; dontSelectMe(): void; } // 直接传入T,数组元素自动校验并推断类型 runOnlyGivenActions<Foo>(["hello", "answer"]);
写法二:带默认值的泛型参数
function runOnlyGivenActions<T extends object, A extends keyof T = keyof T>(actions: readonly A[]) { // 处理actions逻辑 console.log(actions); type T2 = Pick<T, A>; } interface Foo { hello(): string answer(): number; dontSelectMe(): void; } // 仅传入T,A会自动从数组元素推断具体类型 runOnlyGivenActions<Foo>(["hello", "answer"]);
第二种写法里,我们给A设置了默认值keyof T,但TypeScript会优先从传入的数组元素推断A的具体字面量类型,既保证了类型安全,又省去了手动指定A的麻烦。
内容的提问来源于stack exchange,提问作者Guid
相关产品推荐
相关产品推荐

