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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:15:32