TypeScript如何从函数参数获取具名参数键的联合类型?
获取函数具名参数的联合类型
假设我有如下函数:
const myFunc = (rowIndex: number, name: string, props: any): void => { }
我需要获取其参数名的联合类型,即rowIndex | name | props。
我定义了如下类型:
type FuncParams<F extends (...args: any[]) => any> = F extends (...args: infer T) => any ? { [K in keyof T]: T[K] extends any ? K : never }[keyof T] : never;
但该类型返回的是数字字符串形式的联合类型:"0" | "1" | "2"。请问如何修改才能得到具名参数键的联合类型?
解决方案
要提取函数的具名参数名称联合类型,不能直接依赖参数数组的索引键(数组类型的keyof只会返回数字索引字符串),需要利用TypeScript对函数参数名称的类型保留特性,通过对象映射的方式提取真实参数名:
方法一:完整推导写法
type FuncParamNames<F extends (...args: any[]) => any> = F extends (...args: infer P) => any ? P extends Record<keyof P, infer _> ? { [K in keyof P]: K } extends { [_ in keyof P]: infer N } ? N extends string ? N : never : never : never : never;
方法二:简洁写法(结合内置Parameters类型)
type FuncParamNames<F extends (...args: any[]) => any> = keyof { [K in keyof Parameters<F>]: K } extends `${infer N}` ? N : never;
验证效果
用myFunc测试上述类型:
type MyParams = FuncParamNames<typeof myFunc>; // 最终类型:"rowIndex" | "name" | "props"
原理说明
你最初的写法中,infer T得到的是函数参数组成的数组类型,数组的keyof结果是数字索引("0"、"1"),所以只能提取出索引字符串。而新的写法通过将参数数组转换为对象类型,再把对象的键转换为字符串类型,从而获取到函数定义时声明的具名参数名称——TypeScript会在类型系统中保留这些参数名信息,通过映射转换就能拿到预期结果。
内容的提问来源于stack exchange,提问作者Nolesh
相关产品推荐
相关产品推荐

