一旦在联合中包含自定义类,Typescript Union Type就会停止区分

时间:2016-10-13 08:05:49

标签: typescript union

我发现如果有问题的联合类型包含任何类型的用户定义类,那么typescript 2.0.3编译器将编译而不会抱怨无效的赋值。

示例:

class Bar {}

// Complains as expected:
interface Foo {
    bar: number|string
}

// Does not complain, surprisingly:
interface Foo2 {
    bar: number|string|Bar
}

var a = <Foo> {
    bar: 5
};
var a2 = <Foo> {
    bar: "yar"
};
//var a3 = <Foo> {
//    bar: new Date() // compiler complains as expected.
//};

var b = <Foo2> {
    bar: new Date() // compiler does not complain, I am confused.
};

我取消注释a3时得到的编译器错误是:

lib/src/thing.ts(18,10): error TS2352: Type '{ bar: Date; }' cannot be converted to type 'Foo'.
  Types of property 'bar' are incompatible.
    Type 'Date' is not comparable to type 'string | number'.
      Type 'Date' is not comparable to type 'number'.

我希望在分配b时收到相同的错误,但是它会在没有投诉的情况下编译好。

这是一个已知问题吗?或者这是预期的行为,我不明白为什么这应被视为有效?我希望能够依赖联合类型来确保属性是几个方面之一,包括我自己定义的类,所以任何见解都将是最受欢迎的。

先谢谢!

编辑:我做了一些测试,并提出了一个更简单的例子:

class Bar {}

var a = <string|number> 4;
var b = <string|number> "thing";
var c = <string|number> new Bar(); // works: confusing
var d = <Bar> 4;                   // ... confusing
var f = <number> new Bar();        // ... also confusing

1 个答案:

答案 0 :(得分:2)

Typescript使用duck typingwritten in the docs

  

TypeScript的核心原则之一是类型检查的重点   价值观的形状。这有时被称为“鸭子打字”或   “结构子类型”

由于您的Bar类为空,编译器设法将Date对象与Bar匹配,因为没有矛盾。
但是,当您向Bar添加成员或方法时,您会收到错误:

class Bar {
    x: number;
}

var b = <Foo2> {
    bar: new Date()
};

产地:

Type '{ bar: Date; }' cannot be converted to type 'Foo2'.
  Types of property 'bar' are incompatible.
    Type 'Date' is not comparable to type 'string | number | Bar'.
      Type 'Date' is not comparable to type 'Bar'.
        Property 'x' is missing in type 'Date'.

code in playground