TypeScript泛型推断怎么实现
这篇文章主要介绍“TypeScript泛型推断怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“TypeScript泛型推断怎么实现”文章能帮助大家解决问题。
基础类型准备
用一个枚举来定义
Animal
的类型
enumEAnimalType{dog='dog',cat='cat',bird='bird',}
定义不同类型的动物有不同的能力类型
typeDog={/**大叫*/shoutLoudly:()=>void;}typeCat={say:()=>void;}typeBird={/**飞*/fly:()=>void;}
定义一个动物的映射类型
typeAnimalMap={[EAnimalType.dog]:Dog;[EAnimalType.cat]:Cat;[EAnimalType.bird]:Bird;}
最终使用的方式
/***定义一个工厂,用来创建具体动物的实例*@returns返回动物的实例*/functioncreateAnimalFactory<TextendsEAnimalType>():IAnimal<T>{//TODO根据业务具体实现return{}asIAnimal<T>;}//根据泛型创建狗狗的实例constdog=createAnimalFactory<EAnimalType.dog>();dog.shoutLoudly();//根据泛型创建鸟的实例constbird=createAnimalFactory<EAnimalType.bird>();bird.fly()
基于Interface的实现 (失败了)
接着我们创建一个
interface
来定义动物基础接口
exportinterfaceIAnimal<TextendsEAnimalType>extendsIAnimalExtra<T>{id:number;//编号name:string;//名称type:T;//类型}
我们看到IAnimal
接口继承了IAnimalExtra
接口,我们想的是通过泛型T
来动态推导出真实的类型。让我们来看看IAnimalExtra
接口怎么写
写
IAnimalExtra
接口
exporttypeIAnimalExtra<TextendsEAnimalType>{[cinkeyofAnimalMap[T]]:AnimalMap[T][c];}
我们这样写,发现调试控制台报了很多错,具体分析了下错误,接口不支持这种功能。接着我们尝试,改成type
试一下。
最后用
type
去替代IAnimalExtra
exporttypeIAnimalExtra<TextendsEAnimalType>={[cinkeyofAnimalMap[T]]:AnimalMap[T][c];}
我们用type
,果然不不错了,证明我们的思路是对的。乍一看,写的怎么复杂[c in keyof AnimalMap[T]]: AnimalMap[T][c];
不要怕,我们先具体分析一下这段代码,就很好理解了。
先看
AnimalMap[T]
,可以理解从AnimalMap
类型中获取对应的类型,近似js中从对象取值keyof
接受一个Object,生成Object的key的字符串的union(联合)in
可以遍历枚举类型,类似 for...in
整体的功能就是根据泛型T,获取AnimalMap
中的某个类型,遍历。
extends IAnimalExtra<T>
报错了
在我们最终认为可以的情况下,发现有报错了,内容为【接口只能扩展对象类型或对象类型与静态已知成员的交集】
所有内容都基于type 实现
在我们尝试了多次之后,发现Interface
怎么也满足不了需求,接着我们都换成type去试试。
exporttypeIAnimal<TextendsEAnimalType>=IAnimalExtra<T>&{id:number;//编号name:string;//名称type:T;//类型}
这里我们用了&
交叉类型类合并接口的类型。
换成type之后,已能完全满足我们的需求,能根据泛型推断出我们想要的类型。
完整Demo
/***动物枚举*/exportenumEAnimalType{dog='dog',cat='cat',bird='bird',}typeDog={/**大叫*/shoutLoudly:()=>void;}typeCat={say:()=>void;}typeBird={/**飞*/fly:()=>void;}exporttypeAnimalMap={[EAnimalType.dog]:Dog;[EAnimalType.cat]:Cat;[EAnimalType.bird]:Bird;}exporttypeIAnimalExtra<TextendsEAnimalType>={[cinkeyofAnimalMap[T]]:AnimalMap[T][c];}exporttypeIAnimal<TextendsEAnimalType>=IAnimalExtra<T>&{id:number;//编号name:string;//名称type:T;//类型}/***定义一个工厂,用来创建具体动物的实例*@returns返回动物的实例*/functioncreateAnimalFactory<TextendsEAnimalType>():IAnimal<T>{//TODO根据业务具体实现return{}asIAnimal<T>;}//根据泛型创建狗狗的实例constdog=createAnimalFactory<EAnimalType.dog>();dog.shoutLoudly();//根据泛型创建鸟的实例constbird=createAnimalFactory<EAnimalType.bird>();bird.fly();
关于“TypeScript泛型推断怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注主机评测网行业资讯频道,小编每天都会为大家更新不同的知识点。