首页 > 解决方案 > 我可以创建两个从数字或字符串派生的相等类型,然后求和或连接这些类型吗?

问题描述

我正在尝试理解 TypeScript 中的泛型类,但是,我期待一种行为,我遇到了另一种如此不同的观点

而不是使用(这项工作就像一个魅力)

class Concat<T extends string, U extends T> {
    private result: string;
    public n1: U;
    public n2: U;
    init(n1: U, n2: U) {
        this.result = this.n1 + this.n2;
    }
}

class Sum<T extends number, U extends T> {
    private result: number;
    public n1: U;
    public n2: U;
    init(n1: U, n2: U) {
        this.result = this.n1 + this.n2;
    }
}

var concat = new Concat<string, string>();
concat.init("A", "A");

var sum = new Sum<number, number>();
sum.init(1, 3);

使用那个或类似的东西会给我一个错误

class OperatorPlus <T extends number | string, U extends T> {
    private result: number | string;

    public n1: U;
    public n2: U;
    init(n1: U, n2: U) {
        this.result = this.n1 + this.n2;
    }
}

var operator = new OperatorPlus<string, string>();
operator.init("A", "B");

有人可以帮助我吗?

标签: typescripttypescript-typings

解决方案


TypeScript 不允许+对任何不计算为number或 to的东西使用运算符string。您的组合将评估为number | string,这意味着当您将 as n1number 和 as n2number+执行加法时,当操作数之一string将执行连接时,这意味着+以两种方式表现。

这正是受 TS 限制的。最近我写了一篇文章,准确地解释了 TS 这样做的原因 -为什么 TypeScript 限制 + 运算符

还要检查我是否可以number | string在您的示例中用作泛型类型:

var operator = new OperatorPlus<number | string, number | string>();
operator.init("A", 1); // no error

如果某些东西扩展number | string了,则意味着它也可以是number | string,并且两个操作数都可以是这样的,而您恰好遇到了 TS 对此严格的情况。


我们可以让它工作,但在内部需要回退到不健全的状态。但是泛型将被阻止使用联合类型,联合类型实例将不可用。考虑:

class OperatorPlus<
  U extends string | number,
  U1 = (string extends U ? number extends U ? never : string : number),
  > {
    private result: U1;

    public n1: U1;
    public n2: U1;
    init(n1: U1, n2: U1) {
        this.result = (this.n1 as any) + this.n2;
    }
}

var operator = new OperatorPlus<number>();
operator.init(1, 2)// ok
var operator2 = new OperatorPlus<string, string>();
operator2.init('A', 'B') //ok
var operator3 = new OperatorPlus<string | number>();
operator3.init() // cannot be used both arguments never type

as any的,看起来不太好,但操作员现在仅限于使用stringnumber从不使用混合。


推荐阅读