TypeScript基础入门 - 泛型 - 泛型约束
项目实践仓库
1 | https://github.com/durban89/typescript_demo.git |
为了保证后面的学习演示需要安装下ts-node,这样后面的每个操作都能直接运行看到输出的结果。
1 | npm install -D ts-node |
后面自己在练习的时候可以这样使用
1 | npx ts-node 脚本路径 |
泛型
泛型约束
我之前分享的一个例子中,有时候想操作某类型的一组值,并且知道这组值具有什么样的属性。在loggingIdentity例子中,我们想访问arg的length属性,但是编译器并不能证明每种类型都有length属性,所以就报错了。
1 | function loggingIdentity<T>(arg: T): T { |
相比于操作any所有类型,我们想要限制函数去处理任意带有.length属性的所有类型。 只要传入的类型有这个属性,我们就允许,就是说至少包含这一属性。 为此,我们需要列出对于T的约束要求。为此,我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束:
1 | interface LengthDefine { |
现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:
1 | loggingIdentity(3); |
运行后会遇到如下错误提示
1 | ⨯ Unable to compile TypeScript: |
我们需要传入符合约束类型的值,必须包含必须的属性:
1 | loggingIdentity({length: 10, value:3}); |
运行后会得到如下结果
1 | $ npx ts-node src/generics_5.ts |
在泛型约束中使用类型参数
我们可以声明一个类型参数,且它被另一个类型参数所约束。 比如,现在我们想要用属性名从对象里获取这个属性。 并且我们想要确保这个属性存在于对象 obj上,因此我们需要在这两个类型之间使用约束。
1 | function getProperty<T, K extends keyof T>(obj: T, key: K) { |
运行后得到如下错误信息
1 | $ npx ts-node src/generics_5.ts |
在泛型里使用类类型
在TypeScript使用泛型创建工厂函数时,需要引用构造函数的类类型。比如,
1 | function create<T> (c: {new(): T;}): T { |
一个更高级的例子,使用原型属性推断并约束构造函数与类实例的关系。
1 | class Keeper1 { |
运行后得到如下输出
1 | $ npx ts-node src/generics_5.ts |
感觉没在实际应用中使用,很鸡肋呀
本实例结束实践项目地址
1 | https://github.com/durban89/typescript_demo.git |