typescript - 我可以创建两个从数字或字符串派生的相等类型,然后求和或连接这些类型吗?
问题描述
我正在尝试理解 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");
有人可以帮助我吗?
解决方案
TypeScript 不允许+
对任何不计算为number
或 to的东西使用运算符string
。您的组合将评估为number | string
,这意味着当您将 as n1
number 和 as n2
number+
执行加法时,当操作数之一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
的,看起来不太好,但操作员现在仅限于使用string
或number
从不使用混合。
推荐阅读
- azure - Azure API 管理 - 如何访问产品信息
- reactjs - (React-Redux)每当我试图从我的购物车中删除一个项目时抛出“dispatch is not a function”
- python - 不兼容的形状:[64,4,4] 与 [64,4] - 以 4 个变量作为输入的时间序列
- javascript - Angular 9 输入日期
- postgresql - 在 postgresql 中索引 josnb 列
- python - 在 python 中通过鼠标单击选择的 2 个复选按钮之间画一条线
- bash - wait 不等待 while 循环中的进程完成
- apache-spark - 如何根据用户输入过滤数据框
- javascript - 如何检查 form.reset() 是否改变了任何东西
- excel - 循环遍历所有可用的 OLAP 多维数据集过滤器值