TypeScript:如何根据字符串参数推导函数的具体返回类型?
TypeScript动态键名的类型推导方案
问题场景
现有如下TypeScript函数:
function getObjectFromString(str: string): { loading: boolean, [key: string]: any } { const result = { loading: false, }; // 根据输入字符串设置键值 result[str] = true; return result; }
调用const obj = getObjectFromString('foo');时,obj的类型被推导为{ loading: boolean, [key: string]: any },但实际需求是让obj的类型为{ loading: boolean, foo: any },且对任意传入的字符串参数都能自动推导对应键名的具体类型。
可行方案:使用泛型捕获字符串字面量类型
通过泛型可以捕获传入参数的具体字符串字面量类型,进而构造出包含该键名的返回类型。以下是两种实现方式:
方式一:结合Record工具类型
function getObjectFromString<K extends string>(str: K): { loading: boolean } & Record<K, any> { const result = { loading: false, } as { loading: boolean } & Record<K, any>; result[str] = true; return result; }
方式二:直接使用映射类型
function getObjectFromString<K extends string>(str: K): { loading: boolean } & { [P in K]: any } { const result = { loading: false } as any; result[str] = true; return result as { loading: boolean } & { [P in K]: any }; }
方案说明
- 泛型
K extends string用于捕获调用时传入的具体字符串字面量(比如传'foo'时,K就代表字面量类型'foo') - 返回类型通过交叉类型(
&)合并loading属性和动态键名的属性,确保TS能推导出自定义的键名类型 - 函数内部的类型断言(
as)是为了让TS认可动态添加的键属于返回类型的一部分,避免类型报错
更严谨的类型限定
如果需要限定动态键对应的值的类型(比如示例中赋值的是true,属于boolean类型),可以把返回类型里的any替换为具体类型:
function getObjectFromString<K extends string>(str: K): { loading: boolean } & Record<K, boolean> { const result = { loading: false, } as { loading: boolean } & Record<K, boolean>; result[str] = true; return result; }
此时调用getObjectFromString('foo')后,obj.foo的类型会被推导为boolean,比any更安全。
测试效果
const obj = getObjectFromString('foo'); // obj的类型为 { loading: boolean; foo: any }(或boolean,取决于上面的实现) obj.loading; // 类型安全,TS能识别该属性 obj.foo; // 类型安全,TS能识别该属性 obj.bar; // TS会抛出类型错误,提示bar属性不存在
内容的提问来源于stack exchange,提问作者Matheus Dias
相关产品推荐
相关产品推荐

