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

TypeScript中能否通过泛型动态添加对象属性键?

解决方案:用映射类型和交叉类型实现你的需求

当然可以实现!你的两个需求都能通过TypeScript的类型系统特性来解决,下面分情况说明:

1. 让函数返回值保留字符串字面量键的类型推断

你原来的函数返回值会被TypeScript宽泛地推断为{ [x: string]: string },导致无法直接访问obj.foo。要让TypeScript捕获字面量类型的键,我们可以用映射类型明确指定返回类型:

function f<T extends string>(k: T): { [Key in T]: string } {
  // 这里需要类型断言,因为TS无法自动推断动态键的类型
  return { [k]: 'test' } as { [Key in T]: string };
}

const obj = f('foo');
obj.foo; // ✅ 现在可以正常访问,TS能识别foo是存在的属性

映射类型{ [Key in T]: string }会根据泛型T的字面量类型生成对应的对象类型,比如当T是'foo'时,返回类型就是{ foo: string },完美匹配你的需求。

2. 定义包含动态键+固定键的接口/类型

你想要的F<T>类型无法直接用接口实现(因为接口不支持动态的单个键定义),但可以通过交叉类型把“固定属性类型”和“动态键映射类型”合并起来:

interface SomeRandomType { /* 你的类型定义 */ }

// 先定义固定属性的类型
type FixedProperties = {
  otherKey: string;
  anotherKey: number;
};

// 用交叉类型合并动态键和固定属性
type F<T extends string> = FixedProperties & { [Key in T]: SomeRandomType };

// 使用示例
const fObj: F<'bar'> = {
  bar: {}, // 符合SomeRandomType类型
  otherKey: 'example',
  anotherKey: 123
};

fObj.otherKey; // ✅ 正常访问
fObj.anotherKey; // ✅ 正常访问
fObj.bar; // ✅ 正常访问

这样F<T>就同时拥有了泛型T指定的动态键,以及固定的otherKey和anotherKey属性,完全满足你的需求。

补充说明

  • 映射类型[Key in T]是TypeScript用来创建基于现有类型的新对象类型的核心语法,它可以遍历泛型T中的每个类型成员(这里T是单个字符串字面量,所以生成单个键)。
  • 交叉类型&的作用是把多个类型的属性合并到一起,让最终的类型同时拥有所有属性。

内容的提问来源于stack exchange,提问作者Rico Kahler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:05:46