Что такое "Структурный ввод для интерфейсов" в TypeScript
В своем блоге о TypeScript Марк Рендл говорит, что одна из вещей, которые ему нравятся в этом:
"Структурная типизация для интерфейсов. Я действительно хочу, чтобы С# мог это сделать"
Что он имел в виду?
Ответ 1
В основном это означает, что интерфейсы сравниваются по принципу "утка", а не по типу идентификации типов.
Рассмотрим следующий код С#:
interface X1 { string Name { get; } }
interface X2 { string Name { get; } }
// ... later
X1 a = null;
X2 b = a; // Compile error! X1 and X2 are not compatible
И эквивалентный TypeScript код:
interface X1 { name: string; }
interface X2 { name: string; }
var a: X1 = null;
var b: X2 = a; // OK: X1 and X2 have the same members, so they are compatible
Спецификация не охватывает это подробно, но классы имеют "бренды", что означает, что один и тот же код, написанный классами, а не интерфейсами, будет иметь ошибку. Интерфейсы С# имеют бренды и, следовательно, не могут быть неявно преобразованы.
Самый простой способ подумать о том, что если вы пытаетесь преобразовать интерфейс X в интерфейс Y, если X имеет все члены Y, преобразование завершается успешно, хотя X и Y могут не иметь одинаковых имен.
Ответ 2
Подумайте.
class Employee { fire: = ..., otherMethod: = ...}
class Missile { fire: = ..., yetMoreMethod: = ...}
interface ICanFire { fire: = ...}
val e = new Employee
val m = new Missile
ICanFire bigGuy = if(util.Random.nextBoolean) e else m
bigGuy.fire