ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

TypeScript:12、泛型

TypeScript:12、泛型 泛型泛型用于编写类型安全、可复用的函数、类和接口。当代码逻辑相同但具体类型不确定时泛型可以代替不安全的any。一、为什么需要泛型下面的写法虽然可以接受任意类型但会失去类型信息functiontest(arg:any):any{returnarg;}constresulttest(hello);使用any的问题是参数和返回值之间的类型关系没有被表达出来调用者也无法得到准确的类型提示。二、泛型函数使用尖括号声明类型参数functionidentityT(value:T):T{returnvalue;}T是类型参数的名字表示某一个暂时还没有确定的类型。调用函数时TypeScript 会根据参数自动推断TconstnumberValueidentity(100);conststringValueidentity(hello);推断结果numberValue → number stringValue → string三、手动指定泛型类型当编译器无法准确推断或者希望明确表达意图时可以手动指定类型constvalueidentitynumber(100);constmessageidentitystring(hello);泛型名称不一定必须叫T但T、K、V是常见命名方式。四、多个泛型参数一个函数可以同时使用多个泛型参数functiongetSecondT,K(first:T,second:K):K{returnsecond;}constresultgetSecondnumber,string(100,hello);这里T表示第一个参数的类型。K表示第二个参数的类型。返回值类型和第二个参数类型保持一致。五、泛型数组泛型可以描述数组中元素的类型functiongetFirstT(items:T[]):T|undefined{returnitems[0];}constfirstNumbergetFirst([1,2,3]);constfirstNamegetFirst([Tom,Jerry]);这样传入数字数组时返回数字传入字符串数组时返回字符串。六、泛型类类也可以声明泛型classBoxT{prop:T;constructor(prop:T){this.propprop;}}constnumberBoxnewBoxnumber(100);conststringBoxnewBoxstring(hello);BoxT可以根据实例化时传入的类型保存不同类型的数据。七、泛型接口接口也可以使用泛型interfaceResponseDataT{code:number;data:T;}constuserResponse:ResponseData{name:string}{code:200,data:{name:孙悟空}};泛型接口适合描述“外层结构固定内部数据类型不同”的返回结果。八、泛型约束泛型默认可以代表任意类型。如果希望限制泛型范围可以使用extendsinterfaceHasLength{length:number;}functiongetLengthTextendsHasLength(value:T):number{returnvalue.length;}getLength(hello);getLength([1,2,3]);T extends HasLength表示T必须满足HasLength的结构也就是必须具有length属性。下面的调用会报错// getLength(100);因为数字没有length属性。九、泛型和 any 的区别对比项any泛型是否保留类型信息通常不保留保留是否进行类型检查大幅削弱保持是否表达参数和返回值关系不能准确表达可以表达适合场景临时兼容旧代码编写通用类型安全代码示例functionunsafe(value:any):any{returnvalue;}functionsafeT(value:T):T{returnvalue;}十、泛型使用建议泛型名称要能表达用途简单场景可以使用T。不要为了使用泛型而使用泛型类型关系明确时才使用。泛型约束应该尽量表达函数真正需要的能力。能自动推断时不必重复手动传入类型参数。不要用any替代可以表达的泛型关系。十一、常见问题1. 把泛型当成运行时变量泛型只存在于编译阶段运行时不会根据T自动创建数据或执行转换。2. 泛型约束写得过于宽泛如果函数需要访问length就应该用具有length的接口约束而不是让函数参数使用any。3. 泛型参数之间没有关系如果两个泛型参数完全没有关联应考虑是否真的需要同时声明。泛型的价值在于表达类型之间的关系。十二、本章小结泛型可以在不确定具体类型时保留类型安全。泛型函数使用function fnT()形式声明。泛型可以用于函数、类、接口和数组。extends可以约束泛型必须满足某种结构。泛型比any更适合编写可复用代码。
返回列表