如何在TypeScript中根据指定值关联并推断类属性类型
TypeScript 约束类C实例化时参数的对应关系
问题场景
现有如下类结构,需要实现:实例化类C时,prop1的取值与prop2的实例类型严格绑定——当prop1为'a'时,prop2必须是A类实例;当prop1为'b'时,prop2必须是B类实例,避免出现wrong1这类错误组合。
原示例代码:
type accepted = 'a' | 'b'; type objects = A | B; class A { aprop: string[] = []; add(): void {} } class B { myprop: string = ''; anotherprop: number = 1; add(): void {} } class C<T extends objects> { prop1: accepted; prop2: T; constructor(prop1: accepted, prop2: T) { this.prop1 = prop1; this.prop2 = prop2; } } const right1 = new C('a', new A()); const right2 = new C('b', new B()); const wrong1 = new C('a', new B()); // 此处应报错,但当前类型系统无法约束
解决方案
要实现参数间的关联约束,需建立字符串字面量与类类型的绑定关系,以下是两种可行实现:
方式一:构造函数重载
通过为C的构造函数定义重载签名,明确合法的参数组合:
class A { aprop: string[] = []; add(): void {} } class B { myprop: string = ''; anotherprop: number = 1; add(): void {} } class C<T extends A | B> { prop1: 'a' | 'b'; prop2: T; // 重载签名:声明合法参数对应关系 constructor(prop1: 'a', prop2: A); constructor(prop1: 'b', prop2: B); // 实现签名 constructor(prop1: 'a' | 'b', prop2: A | B) { this.prop1 = prop1; this.prop2 = prop2 as T; } } const right1 = new C('a', new A()); // 正常通过 const right2 = new C('b', new B()); // 正常通过 const wrong1 = new C('a', new B()); // 类型错误,符合预期
方式二:映射类型+泛型约束
先定义字符串到类类型的映射,再通过泛型参数绑定关系,让TypeScript自动推断类型:
class A { aprop: string[] = []; add(): void {} } class B { myprop: string = ''; anotherprop: number = 1; add(): void {} } // 定义字符串与类类型的映射关系 type PropMap = { 'a': A; 'b': B; }; class C<K extends keyof PropMap> { prop1: K; prop2: PropMap[K]; constructor(prop1: K, prop2: PropMap[K]) { this.prop1 = prop1; this.prop2 = prop2; } } const right1 = new C('a', new A()); // 自动推断K为'a',prop2类型为A const right2 = new C('b', new B()); // 自动推断K为'b',prop2类型为B const wrong1 = new C('a', new B()); // 类型错误,符合预期
说明
- 方式一适合参数组合较少的场景,直观易懂;
- 方式二扩展性更强,后续新增对应关系时只需修改
PropMap即可。
内容的提问来源于stack exchange,提问作者user13749429
相关产品推荐
相关产品推荐

