使用联合类型“number | string”

时间:2016-03-21 11:28:24

标签: typescript

请考虑以下代码段(另请参阅TS Playground):

var nr: number = 123456;
var str: string = "2015-01-01T12:00:00";
var both: number | string = 123456;

var myDate: Date;

myDate = new Date(nr);
myDate = new Date(str);
myDate = new Date(both); // <-- Compile error

最后一行给出了编译错误:

  

类型number | string的参数不能分配给'string'类型的参数。类型'number'不能指定为'string'类型。

但是,由于这两种类型都有一个Date(...)构造函数,我认为上述方法可行。

我可以解决这个问题,因为还有另一个构造函数使用any参数:

myDate = new Date(<any> both);

但是,如果那个构造函数不在那里,例如,如果这种情况发生在我自己的班级?

有没有办法让它正常工作?或者联合类型是一种设计气味,这表明我的定义需要改变?

我已经检查了TS Handbook,但它没有关于联合类型的部分。我自己试过解决它,但没有超越上面提到的<any>技巧。我已经完成了关于SO的建议重复和类似问题,但到目前为止还没有找到答案。

2 个答案:

答案 0 :(得分:4)

您可以扩展Date的构造函数接口以支持此功能;可能不是最好的解决方案,但似乎有效...

interface DateConstructor {
    new (value: number | string): Date;
}

var nr: number = 123456;
var str: string = "2015-01-01T12:00:00";
var both: string | number = "123456";

var myDate: Date;

myDate = new Date(nr);
myDate = new Date(str);
myDate = new Date(both); // <-- No more compile error

我认为联合类型在TypeScript中被视为一等公民,例如:string | number是它自己的类型,stringnumber可以分配。在这方面,value: stringvalue: number与类型签名value: string | number不匹配 - 因此有必要扩展DateConstructor以支持此功能。

答案 1 :(得分:3)

这已经在Typescript github项目中进行了讨论。

https://github.com/Microsoft/TypeScript/issues/1805

总而言之,将这项工作放在像你所呈现的那种简单的情况下会很好,但在更复杂的情况下它会崩溃。

  

本质上,重载集用于创建将参数1的类型与参数2的类型绑定的信息(并且可以同样用于将其与返回类型联系起来)。使用联合类型,信息丢失,允许任何参数类型组合。

他们的建议是制定编码标准,说功能类型应该使用联合类型而不是重载。

  

参见#6735 - 我们讨论过,我们的计划是通过提供TS Lint规则和指导来减轻这种情况,你不应该写一系列在union类型中具有等效表示的重载。

     

以某种方式使这项工作作为签名重载解析的一部分太复杂了。