TypeScript类中如何声明与已有对象键名相同的泛型映射对象
实现类属性间的键一致类型映射
嘿,我来帮你搞定这个TypeScript类型映射的需求!你想要让ob2和ob1拥有完全相同的键名,同时值类型能自动从Wrapper的泛型里提取出来对吧?咱们用TypeScript的泛型+映射类型就能完美实现,而且类型安全拉满。
第一步:先明确Wrapper类型(如果还没定义的话)
假设你的Wrapper是一个包裹原始类型的结构,比如常见的:
// 示例Wrapper类型,可根据你的实际结构调整 type Wrapper<T> = { value: T };
第二步:泛型类实现键一致的类型映射
把你的类改成泛型类,让TypeScript动态捕获传入对象的键和内部类型:
class C<T extends Record<string, Wrapper<any>>> { // ob1保留传入的原始结构,类型由泛型T捕获 ob1: T; // ob2的键和T完全一致,值类型自动从Wrapper中提取 ob2: { [K in keyof T]: T[K] extends Wrapper<infer U> ? U : never }; constructor(o?: T) { this.ob1 = o || ({} as T); // 运行时生成ob2:遍历ob1的键,提取每个Wrapper的内部值 this.ob2 = Object.fromEntries( Object.entries(this.ob1).map(([key, wrapper]) => [key, wrapper.value]) ) as typeof this.ob2; } }
关键部分解释
- 泛型约束
T extends Record<string, Wrapper<any>>:确保传入的构造函数参数必须是键为字符串、值为Wrapper类型的对象,这样TypeScript能精准捕获每个键对应的Wrapper泛型类型。 - 映射类型
{ [K in keyof T]: ... }:遍历T的所有键K,用infer U从Wrapper<U>中自动提取出被包裹的原始类型U。这样ob2的每个键的类型都会和ob1对应键的Wrapper内部类型完全匹配。 - 运行时生成
ob2:通过Object.fromEntries和map遍历ob1,把每个Wrapper的内部值提取出来赋值给ob2的对应键,最后用类型断言告诉TypeScript这就是正确的类型(因为TypeScript没办法自动推导fromEntries的精确类型)。
测试用例
来看看实际使用的效果:
// 定义一个符合要求的输入对象 const userData = { username: { value: "ConstiP" } as Wrapper<string>, age: { value: 28 } as Wrapper<number>, isActive: { value: true } as Wrapper<boolean> }; // 创建类实例 const cInstance = new C(userData); // 类型完全安全 cInstance.ob2.username; // 类型是string,值为"ConstiP" cInstance.ob2.age; // 类型是number,值为28 cInstance.ob2.isActive; // 类型是boolean,值为true // 如果你尝试访问不存在的键,TypeScript会报错 cInstance.ob2.nonExistentKey; // ❌ 类型错误:不存在该属性
适配不同的Wrapper结构
如果你的Wrapper不是{value: T}的结构,比如是函数或者其他形式,只需要调整infer的逻辑就行。比如如果Wrapper是一个函数:
type Wrapper<T> = (val: T) => void; // 对应的ob2类型就改成 ob2: { [K in keyof T]: T[K] extends (val: infer U) => void ? U : never };
内容的提问来源于stack exchange,提问作者Consti P
相关产品推荐
相关产品推荐

