如何从多个属性动态构造TypeScript高级类型?
解决多参数构造
X类型对象的问题 首先,你的泛型类型定义type X<Property extends string> = { [K in Property]: K }是完全正确的,它能把字符串字面量的联合类型转换成键值均为自身的对象类型。接下来我们只需要完善构造函数的实现,让它能处理多个参数并正确生成目标对象。
你已经把函数签名改成了剩余参数形式,这一步是对的。现在要做的就是遍历所有传入的属性,逐个将它们作为键和值添加到结果对象中,这里可以用数组的reduce方法来实现累加:
// 保留你的类型定义 type X<Property extends string> = { [K in Property]: K }; // 改造后的构造函数 let x = <Props extends string>(...p: Props[]): X<Props> => { // 使用reduce遍历参数,逐个构建对象 return p.reduce((result, prop) => { result[prop] = prop; return result; }, {} as X<Props>); // 用类型断言告诉TS初始对象最终会符合X<Props>类型 };
为什么这样可行?
reduce方法会遍历传入的所有属性参数,每次迭代都把当前属性作为键和值添加到累加对象中,最终得到包含所有属性的目标对象。- 类型层面上,剩余参数
...p: Props[]会自动将所有传入的字符串字面量参数合并成一个联合类型(比如传入"name", "age"时,Props就是"name" | "age"),正好匹配X类型的泛型参数要求。 - 初始的
{} as X<Props>类型断言是必要的:因为TypeScript无法自动推断空对象会逐步变成X<Props>类型,我们需要明确告诉编译器最终的类型结构。
测试验证
调用x("name", "age", "email")时,TypeScript会自动推断返回类型为X<"name" | "age" | "email">,也就是:
{ name: "name"; age: "age"; email: "email"; }
完全符合你的预期。如果传入重复参数(比如x("name", "name")),由于联合类型会自动去重,返回的类型依然是X<"name">,对象也只会保留一个name键。
内容的提问来源于stack exchange,提问作者user11367277
相关产品推荐
相关产品推荐

