文章目录
1、泛型实现类型参数化
- 使用方式
- 通过 <类型> 的方式将类型传递给函数
- 通过类型推导(type argument inference),自动推到出我们传入变量的类型:
- 在这里会推导出它们是 字面量类型的,因为字面量类型对于我们的函数也是适用的
- 平时在开发中我们可能会看到一些常用的名称:
- T:Type的缩写,类型
- K、V:key和value的缩写,键值对
- E:Element的缩写,元素
- O:Object的缩写,对象
// 定义函数:将传入的内容返回 function bar<Type>(arg: Type): Type {
return arg } // 完整写法 const res1 = bar<number>(123) const res2 = bar<string>('abc') const res3 = bar<{
name: string }>({
name: 'why' }) // 省略写法 const res4 = bar('aaa') const res5 = bar() // 元组:useState函数 function useState<Type>(initialState: Type): [Type, (newState: Type) => void] {
let state = initialState function setState(newState) {
state = newState } return [state, setState] } // 初始化count const [counte, setCount] = useState<number>(100) const [bool, setBool] = useState(false) const [message, setMassage] = useState<string>('hello World') const [banners, setBanners] = useState<any[]>([]) //传入多个类型 function foo<Type, Element>(arg1: Type, arg2: Element) {
} foo<string, number>('why', 18)
2、泛型接口
interface IKun<Type = number> {
name: string age: Type height: Type } const ikun: IKun<number> = {
name: 'why', age: 18, height: 1.88, } const ikun1: IKun = {
name: 'kobe', age: 30, height: 29.9, }
3、泛型类
class Point<Type = number> {
x: Type y: Type constructor(x: Type, y: Type) {
this.x = x this.y = y } } const p1 = new Point(10, 20) console.log(p1.x) const p2 = new Point<string>('123', '321') console.log(p2.x)
4、泛型约束(Generic Constraints)
- 基本使用
interface ILength { length: number } function getLength(arg: ILength) { } const length1 = getLength('aaaa') const length2 = getLength(['aaa', 'bbb', 'ccc']) const length3 = getLength({ length: 100 }) // 获取传入的内容,这个内容必须有length属性 // Type相当于是一个变量,用于记录本次调用的类型,所以在整个函数的执行周期中,一直保留着参数的类型 function getInfo<Type extends ILength>(args: Type): Type { return args } const info1 = getInfo('aaaa') const info2 = getInfo(['aaa', 'bbb', 'ccc']) const info3 = getInfo({ length: 100 }) // getInfo() // getInfo({})
- 在泛型约束中使用类型参数(Using Type Parameters in Generic Constraints)
// 传入的key类型,obj当中key的其中之一 function getObjectProperty<O, K extends keyof O>(obj: O, key: K) { return obj[key] } const info = { name: 'why', age: 18, height: 1.88, } const name = getObjectProperty(info, 'name')
5、映射类型(Mapped Types)
- 映射类型建立在索引签名的语法上:
- 映射类型,就是使用了 PropertyKeys 联合类型的泛型;
- 其中 PropertyKeys 多是通过 keyof 创建,然后循环遍历键名创建一个类型;
// TypeScript提供了映射类型:函数 // 映射类型不能使用interface定义 type MapPerson<Type> = {
// 索引类型以此进行使用 [Property in keyof Type]: Type[Property] } interface IPenson {
name: string age: number } type NewPerson = MapPerson<IPenson>
6、映射修饰符(Mapping Modifiers)
- 修饰符:
- 一个是 readonly,用于设置属性只读;
- 一个是 ? ,用于设置属性可选;
- 你可以通过前缀 - 或者 + 删除或者添加这些修饰符,如果没有写前缀,相当于使用了 + 前缀。
type MapPerson<Type> = {
-readonly [Property in keyof Type]+?: Type[Property] } interface IPerson {
name: string age: number height: number address: string } type IPersonOptional = MapPerson<IPerson> const p: IPersonOptional = {
}
7、内置工具和类型体操
- 类型系统其实在很多语言里面都是有的,比如Java、Swift、C++等等,但是相对来说TypeScript的类型非常灵活:
- 这是因为TypeScript的目的是为JavaScript添加一套类型校验系统,因为JavaScript本身的灵活性,也让TypeScript类型系统不得不增加更加的功能以适配JavaScript的灵活性;
- 所以TypeScript是一种可以支持类型编程的类型系统;
- 这种类型编程系统为TypeScript增加了很大的灵活度,同时也增加了它的难度:
- 如果你不仅仅在开发业务的时候为自己的JavaScript代码增加上类型约束,那么基本不需要太多的类型编程能力;
- 但是如果你在开发一些框架、库,或者通用性的工具,为了考虑各种适配的情况,就需要使用类型编程;
- TypeScript本身为我们提供了类型工具,帮助我们辅助进行类型转换(前面有用过关于this的类型工具)
- 很多开发者为了进一步增强自己的TypeScript编程能力,还会专门去做一些类型体操的题目:
- https://github.com/type-challenges/type-challenges
- https://ghaiklor.github.io/type-challenges-solutions/en/
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/pythonbc/1183.html