在他关于 TypeScript 的博客文章中,Mark Rendle 说,他喜欢它的一件事是:
“接口的结构类型。我真希望 C# 能做到这一点”
他那是什么意思?
基本上,这意味着接口是在“鸭子类型”的基础上进行比较的,而不是在类型标识的基础上进行比较。
考虑以下 C# 代码:
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
规范没有详细介绍这一点,但是类具有“品牌”,这意味着使用类而不是接口编写的相同代码会出错。C# 接口确实有品牌,因此不能隐式转换。
考虑它的最简单方法是,如果您尝试从接口 X 到接口 Y 的转换,如果 X 具有 Y 的所有成员,则转换成功,即使 X 和 Y 可能没有相同的名称。
想一想。
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
如果我们说:
interface IButtonEvent { fire: = ...}
interface IMouseButtonEvent { fire: = ...}
...
TypeScript 将允许这样做,C# 不会。
由于 TypeScript 旨在与使用“松散”类型的 DOM 一起工作,因此它是 typescript 的唯一明智选择。
我把它留给读者来决定他们是否喜欢“结构类型”……