我是Typescript的新手,只是一个关于扩展类型形状的泛型类的问题,下面是一些示例代码:
class DataCollection<T extends { name: string }> {
...
}
这是有效的代码,似乎一个类可以扩展Sharp类型,但是如果我们这样编码,那是不正确的:
type Person = {
name: string
}
class DataCollection extends Person { // invalid code
...
}
这是无效的,因此类无法扩展Sharp类型。
通过这种方式,我们只能将类型Person
作为接口和代码:
type Person = {
name: string
}
class DataCollection implements Person { //valid code
...
}
这意味着,将通用类用作以下内容更明智:
class DataCollection<T implements { name: string }> {
...
}
那么为什么泛型类只能扩展类型形状而不能实现类型形状?
答案 0 :(得分:1)
尽管共享相同的语法,但这里有几个概念都不同。
引用type Name = ...
定义的标准方法是类型别名而不是类型形状
首先,类型仅在编译时存在。因此,根据定义,在运行时没有任何东西可以依赖它们。这意味着在已编译的js中将不会以任何方式存在类型别名Person
人。
类具有双重性质,它们的名称既表示类型(类的实例类型)又表示运行时值(用于初始化对象的构造函数)。
您说class DataCollection extends Person
的意思是,在运行时时,类DataCollection
需要向其原型链中添加Person
的原型。由于类型别名在编译过程中被删除,因此类DataCollection
的原型链中没有添加任何内容,这使得该声明对于类型别名(或接口)毫无意义。
当您说class DataCollection implements Person
时,是在要求编译器确保在编译时class DataCollection
的所有成员都具有Person
类型的适当类型。这是一个纯粹的编译时操作,因此在这里使用类型别名是可以的。
T
中的class DataCollection<T>
是通用类型参数。通用类型参数可用于使一个类可用于多种数据类型,同时保留有关基础类型的信息:
class DataCollection<T> {
add(value: T) {}
}
var c = new DataCollection<number>();
c.add(1)
c.add("1") // error
请注意,T
从未在运行时表达式中使用,仅在类型注释中使用,我们决不能在表达式中使用T
(例如new T()
无效) 。 T
只是在编译时检查类的某些方面(参数,成员,返回值)是否具有在实例化类时指定的特定类型(在这种情况下,number
在{{1}中指定)。
有时我们需要更多有关new DataCollection<number>
的信息。例如,我们可能想要一个T
成员。这是onAdded
进入的地方。它使我们可以将DataCollection<T extends TYPE>
约束为另一种指定类型的子类型:
T
语法type WithAdd = { onAdd(): void }
class DataCollection<T extends WithAdd> {
add(value: T) {
value.onAdd(); // ok since onAdd is on the constraint of T
value.onAdded(); // error since onAdded is not on the constraint of T
}
}
class Person {
name!: string;
onAdd(): void { }
}
var cErr = new DataCollection<number>(); // error number does not have onAdd
var c = new DataCollection<Person>()
c.add(new Person())
c.add({ onAdd() { } }) // error not a Person
在打字稿中没有任何意义。由于约束中的DataCollection<T implements { name: string }>
已经只处理类型,因此说extends
扩展类型或T
实现类型之间的含义确实没有区别。在这两种情况下,T
都是指定类型的子类型,因此在没有添加任何值的情况下,两者都将造成混乱。至于为什么选择T
而不是extends
,这是所有人的猜测。