You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从多个属性动态构造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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:21:09