2016-10-13 4 views
0

Я обнаружил, что компилятор 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, но компилируется нормально без жалоб ,

Это известная проблема? Или это ожидаемое поведение, и я не вижу, почему это следует считать действительным? Я хотел бы иметь возможность полагаться на тип объединения, чтобы гарантировать, что это свойство является одной из нескольких вещей, включая классы, которые я определил сам, так что любые идеи были бы наиболее оценены.

Спасибо, заранее!


Edit: я сделал немного больше тестирования и придумали еще более простой пример:

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

Машинопись использует duck typing как written in the docs:

One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”

С вашего Bar класса пуст, компилятору удается сопоставить объект Date с Bar, потому что нет противоречия s.
Но как только вы добавляете элемент или метод 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)

+0

Хотя технически, утиная типизация не действительно так же как и структурная типизация. Утиная печать - это скорее явление времени выполнения, которое заботится только о существовании использованных членов, а структурная типизация - это сравнение времени для компиляции типов. – Alex

 Смежные вопросы

  • Нет связанных вопросов^_^