我有一个父类 A,一个 A 的子类 B,以及一个 B 的子类 C。
class A {}
class B extends A {}
class C extends B {}
我想创建一个泛型函数 f,它的唯一参数是对扩展 B 的类的示例的约束。
在我对typescript的理解中,函数应该如下所示:
function f<T extends B>(p: T): any {}
然而,当我把A或任何其他类型(数字、字符串等)的示例作为参数传递时,ts类型检查器并不抱怨。
const a = f(new A()); // should complain
const b = f(new B());
const c = f(new C());
const d = f(123); // should complain
我是不是漏掉了什么明显的东西?是不是类型检查器的配置问题?
2条答案
按热度按时间aoyhnmkz1#
Typescript有结构类型。编译器检查的是结构,而不是实际(名义)类型。
由于类型是空的(没有成员),满足它们的类型比预期的要多得多。
但是,向类型中添加成员(例如,向B添加A中不存在的成员),以便编译器可以检查结构,并检查约束,正如您所期望的那样
tkclm6bt2#
你不需要泛型。泛型是用来从你的泛型类型中创建不同类型的函数。这里你只需要寻找一个特定类型的函数,它只接受
B
的示例。此外,你最好在类中定义一些属性,否则所有空类示例都将被赋值给空类示例。This github issue有更多信息。原因似乎是结构类型系统。
结构化类型系统(或基于属性的类型系统)是类型系统的主要类别,其中类型兼容性和等价性由类型的实际结构或定义确定,而不是由诸如名称或声明位置之类的其他特征确定。
这里是this的wiki
你可以看看这个来理解:
连结(请忽略Playground内的禁止使用警告,与问题无关)
请注意,如果从类中删除属性,错误将消失。
PS:你仍然可以在这里使用泛型,比如:
链接