TypeScript泛型:如何从泛型对象属性中设置类型
解决TypeScript Container类类型安全问题
你的代码报错根源在于:Container类的target属性被推断为A | B的联合类型,TypeScript无法确定它具体是A还是B实例,因此禁止访问仅存在于B上的bbb1属性。
要在保留类型安全的同时实现需求,你可以给Container类新增一个泛型参数,用来明确指定目标属性的键,让target的类型精确对应到该键的值类型,而非所有属性值的联合类型。
单目标属性的解决方案
class A { aaa1 = "aaa1" aaa2 = "aaa2" } class B { bbb1 = "bbb1" bbb2 = "bbb2" } // 新增泛型参数K,限定为T的键类型 class Container<T, K extends keyof T> { all: T; target: T[K]; // target类型精确为目标键对应的值类型 constructor(resources: T, targetKey: K) { this.all = resources; this.target = resources[targetKey]; } } const obj = { a: new A(), b: new B() }; // 实例化时传入目标键,TypeScript自动推导K为"b",target类型为B const container = new Container(obj, "b"); console.log(container.target.bbb1); // 类型安全,无报错
多目标属性的扩展方案
如果需要同时持有多个目标属性且保持类型安全,可以将泛型参数K设为键的联合类型,让targets对象的类型精确匹配选中的属性:
class Container<T, K extends keyof T> { all: T; targets: { [Key in K]: T[Key] }; constructor(resources: T, targetKeys: K[]) { this.all = resources; this.targets = targetKeys.reduce((acc, key) => { acc[key] = resources[key]; return acc; }, {} as { [Key in K]: T[Key] }); } } const container = new Container(obj, ["a", "b"]); console.log(container.targets.a.aaa1); // 类型安全 console.log(container.targets.b.bbb1); // 类型安全
内容的提问来源于stack exchange,提问作者Don John
相关产品推荐
相关产品推荐

