在 TypeScript 中没有办法做到这一点。它基本上是一个运行时约束。
在 C# 中,这new
意味着您实际上正在为函数创建一个新名称,该名称仅在通过派生类型的表达式时才可见,但通过基类型的表达式使用该名称仍然可以看到基成员(包括在基案例实施本身,关键)。
在 TypeScript/JavaScript 中,对象中只有一个“槽”,派生类实际上是在覆盖基类的成员。您通过覆盖该成员来破坏基类的可能性非常高,因为基类无法引用它认为拥有的成员。
编辑添加:您可以通过这种方式添加专业化,只要它们实际上是正确的(与在 C# 中相同,您通常只new
在破坏基类形状时才使用关键字)。如果您的类型在运行时是一致的(即您实际上可以使用 Derived 代替 Base),则此限制实际上不应该成为问题:
declare class Item {}
declare class SpecialItem extends Item { }
declare class MyBase { data: Item[]; }
declare class MyData { }
declare class MyDerived extends MyBase { data: SpecialItem[]; /* OK */ }
declare class MyDerived2 extends MyBase { data: number[]; /* not OK */ }
在您的示例中,data
inMyDerived
需要是一个MyData[]
(否则您将违反MyBase
合同):
declare class MyBase { data: any[]; }
declare class MyData { }
declare class MyDerived extends MyBase { data: MyData[]; /* OK */ }