我们会得到一段报错,这是新手 TypeScript 开发者常常犯的错误,编译器告诉我们,参数 obj 实际上是 {},因此后面的 key 是无法在上面取到任何值的。
因为我们给参数 obj 定义的类型就是 object,在默认情况下它只能是 {},但是我们接受的对象是各种各样的,我们需要一个泛型来表示传入的对象类型,比如T extends object:
function getValue<T extends object>(obj: T, key: string) { return obj[key] // error }
这依然解决不了问题,因为我们第二个参数 key 是不是存在于 obj 上是无法确定的,因此我们需要对这个 key 也进行约束,我们把它约束为只存在于 obj 属性的类型,这个时候需要借助到后面我们会进行学习的索引类型进行实现 <U extends keyof T>,我们用索引类型 keyof T 把传入的对象的属性类型取出生成一个联合类型,这里的泛型 U 被约束在这个联合类型中,这样一来函数就被完整定义了:
function getValue<T extends object, U extends keyof T>(obj: T, key: U) { return obj[key] // ok }
另外提一个多重泛型约束的写法,可以当作拓展:
interface firstInterface { first(): number } interface secondInterface { second(): string } class Demo<T extends firstInterface & secondInterface >{ ... }
在泛型里使用类类型
在TypeScript使用泛型创建工厂函数时,需要引用构造函数的类类型。比如:
function create<T>(type: {new(): T; }): T { return new type(); }
参数type的类型{new(): T}就表示此泛型T是可被构造的,在被实例化后的类型是泛型 T。
总结
到此这篇关于前端深入理解Typescript泛型概念的文章就介绍到这了,更多相关Typescript 泛型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章: