我刚刚从this question的答案中学到了使用区分元组作为参数的方法,但是当我在一些旧代码上尝试使用该概念时,我发现我无法使其正常工作预期。考虑以下示例:
class Fraction {
constructor(r: Rational) {
/* Not important */
}
}
type Rational = number | Fraction;
class Couple {
private _x: Fraction;
private _y: Fraction;
constructor(c: Couple);
constructor(x: Rational, y: Rational);
constructor(...r: [Couple] | [Rational, Rational]) {
if(r[0] instanceof Couple) r = [r[0]._x, r[0]._y]; // pay attention here
this._x = new Fraction(r[0]);
this._y = new Fraction(r[1]);
}
}
我希望在上面指出的那行之后,TypeScript应该得出结论,r
只能是[Rational, Rational]
类型,接下来的两行应该没有问题,但这不是案件。为什么会这样?如何在仍然使用元组想法的情况下解决此问题?
答案 0 :(得分:1)
问题在于此元组实际上不是受歧视的联合。受歧视的联合必须具有判别属性,如果满足以下条件,则该属性就是判别属性:
请参阅this评论
如果我们在第一个元组中添加一个额外的元素,则可以将其转换为有区别的并集,因此我们满足上面概述的第二种情况:
class Fraction {
constructor(r: Rational) {
/* Not important */
}
}
type Rational = number | Fraction;
class Couple {
private _x: Fraction;
private _y: Fraction;
constructor(c: Couple);
constructor(x: Rational, y: Rational);
constructor(...r: [Couple, undefined?] | [Rational, Rational]) {
if(r[1] === undefined) r = [r[0]._x, r[0]._y];
this._x = new Fraction(r[0]); // ok
this._y = new Fraction(r[1]); // ok
}
}