TypeScript-泛型约束
小开开 2020-12-04 17:17:16 2020-12-04 86 0
泛型约束
必须谨慎使用类型变量,参考下面的例子:
// 定义泛型函数function getLength<T>(arg: T): number { // 错误,编译器不知道类型变量T是否包含属性length,默认为不存在 // error TS2339: Property 'length' does not exist on type 'T' return arg.length;}
上例中没有任何地方表明 T
类型的参数 arg
包含属性 length
,因而编译器认为不存在属性 length
报错。为了改正上述代码,需要约束类型变量 T
必须包含属性 length
语法
类型变量 extends 类型
类型约束关键字为 extends
,和继承关键字一样。实际上,类型约束跟继承同义,类型变量继承了被约束类型的所有成员
// 声明接口interface WithLength { length: number;}// 正确,T现在被接口类型WithLength约束,包含属性 lengthfunction getLength<T extends WithLength>(arg: T): number { return arg.length;}
默认类型
参考下面的例子:
interface MyType<T> { value: T;}// error TS2314: Generic type 'MyType<T>' requires 1 type argument(s)let a: MyType = { value: "hello world"}
泛型在使用的时候必须用实际类型取代类型参数,假如同上面那样,编译器就无法判定a.value
的实际类型是什么(有可能是任何类型),因而报错。修正这个错误很简单,只需要在使用的时候传递类型参数即可:
// 正确let a: MyType<string> = { value: "hello world"}
每次都用尖括号语法注解确实挺烦的,尤其是在有些情况下,其他人使用 MyType
接口的时候可能并不知道这是一个泛型接口声明。TypeScript提供了默认类型语法:
类型变量 = 类型
参考下面的例子:
interface MyType<T = string> { value: T;}// 正确,在类型参数没有显示指定的情况下,采用了默认类型 stringlet x1: MyType = { value: "hello world"}// 等价于let x1: MyType<string> = { value: "hello world"}// 错误, error TS2322: Type 'number' is not assignable to type 'string'let x2: MyType = { value: 123}
- 作者:joye
- 出处:https://github.com/joye61