用来创建可复用组件的工具,我们称之为泛型(generics)。利用泛型,我们可以创建一个支持众多类型的组件,这让用户可以使用自己的类型消费(consume)这些组件
泛型类型变量
1 | function identity<Type>(arg:Type):Type{ |
Type允许我们捕获用户提供的类型,使得我们接下来可以使用这个类型。调用函数里的<>明确设置Type为string作为函数调用的一个参数
或者直接使用类型参数推断
1 | let output=identity("myString") |
假如我们要使用arg的.length属性,如果传进的参数不拥有length属性,则会报错,有两种写法:
使用Type类型的数组而不是Type
1 | function loggingIdentity<Type>(arg:Type[]):Type[]{ |
泛型函数loggingIdentity接受一个Type类型参数和一个实参arg,实参arg是一个Type类型数组,该函数返回一个Type类型数组,使用类型变量Type,作为我们使用类型的一部分,而不是之前的一整个类型
1 | function loggingIdentity<Type>(arg:Array<Type>):Array<Type>{ |
泛型接口
泛型函数作为接口的函数
1 | interface GenericIdentityfn{ |
有时,我们会将泛型参数作为整个接口的参数,可以让我们清楚知道传入的是什么参数(GenericIdentityfn
1 | interface GenericIdentityfn{ |
泛型类
类似于泛型接口,下面这个例子,不仅可以使用number类型,也可以使用其他类型,和接口一样,可以把类型参数放在类上,确保类中所有属性使用相同类型
一个类有两部分:静态部分和实例部分,泛型类仅仅对实例部分生效,静态成员不能使用类型参数
1 | class GenericNumber<NumType>{ |
泛型约束
在接口中列出约束条件,然后使用接口和extends关键词实现约束
1 | interface Lengthwise { |
使用类型参数约束另一个类型参数
要获取一个对象给定属性名的值,我们需要确保我们捕获获取obj上不存在的属性,所以在两个类型之间建立一个约束:
1 | function getProperty<Type,Key extends keyof Type>(obj:Type,key:Key){ |
在泛型中使用类
在TypeScript,当使用工厂模式创建实例时,有必要通过他们的构造函数推断出类的类型
1 | function create<Type>(c:{new():Type}):Type{ |
参考:
https://www.typescriptlang.org/docs/handbook/2/generics.html
https://ts.yayujs.com/handbook/Generics.html#%E6%B3%9B%E5%9E%8B-generics