使用联合类型调用新日期"number | string"



请考虑以下代码片段(另请参阅 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 的参数不能分配给类型为"字符串"的参数。类型"数字"不能分配给类型"字符串"。

但是,由于这两种类型都有一个Date(...)构造函数,因此我认为上述方法可以正常工作。

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

myDate = new Date(<any> both);
但是,如果

该构造函数不存在,例如,如果这种情况发生在我自己的类中怎么办?

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

我已经检查了 TS 手册,但它没有关于工会类型的部分。我尝试过自己解决它,但没有通过上面提到的<any>技巧。我已经浏览了SO上建议的重复项和类似问题,但到目前为止还没有找到答案。

您可以扩展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以支持这一点是有意义的。

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

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

总而言之,在

像您介绍的简单情况下进行这项工作会很好,但在更复杂的情况下,它会分崩离析。

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

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

请参阅 #6735 - 我们讨论过,我们的计划是通过提供 TS Lint 规则和指导来缓解这种情况,即您永远不应该编写一系列在联合类型中具有等效表示形式的重载。

以某种方式将其作为签名重载解决方案的一部分太复杂了。

相关内容

最新更新