如何在Typescript中动态将字符串作为返回对象key类型获得正确类型提示
解决方案
核心是通过泛型捕获传入键的字面量类型,再拼接返回类型:
修改后的完整代码
import { v4 as uuid } from 'uuid'; const withPrimaryKey = <K extends string>(key: K) => { return <T extends object>(input: T): Omit<T, K> & Record<K, string> => { return { ...input, [key]: uuid() } as Omit<T, K> & Record<K, string>; } } export default withPrimaryKey;
效果验证
调用时不需要手动声明返回类型,TS会自动推导:
const injectPrimaryKey = withPrimaryKey('categoryId'); const input = { name: 'books' }; const data = injectPrimaryKey(input); // 可以正常识别data有categoryId属性,类型为string,不会出现类型报错 console.log(data.categoryId);
原理解释
- 原代码中
key的类型声明为string,TS只会将其识别为通用字符串类型,不会保留传入的具体字面量(如categoryId)的类型信息,因此无法推导返回对象中新增的键。 - 新增泛型
K extends string后,TS会自动捕获传入的字符串字面量作为K的实际类型,通过Record<K, string>即可定义出对应键的类型,使用Omit<T, K>是为了兼容原对象可能存在同名键的场景,保证运行时覆盖的逻辑和类型定义一致,交叉后即可得到完整的返回类型。 - 代码中的类型断言是为了规避TS对泛型计算属性的默认推导偏差,保证返回类型符合预期。
边界场景说明
如果传入的key是运行时动态生成的变量(非字面量),TS无法在编译阶段获取到具体键名,这种场景下最优方案是手动声明返回类型,或者为返回对象添加索引签名。
内容的提问来源于stack exchange,提问作者kemicofa
相关产品推荐
相关产品推荐

