建立实例ts文件generics.ts数组
在index.ts内引入编辑器
fill是填充数组,建立的数组的元素数是times,填充的值就是接收的value的值函数
这里传入一个2的数量,这样返回的就是5个2的数组spa
返回每一个都+1的结果3d
返回每一个元素的length这样就是有错误的,由于咱们的数值类型是没有length这个属性的code
传入字符串,是有length属性的对象
虽然是能够,可是丢失了类型的检测。这里咱们就须要用到泛型blog
使用泛型约束函数的类型索引
泛型变量T,调用函数的时候会手动传入这个类型,T就表明固定的一种类型,这样传入的value的值类型也是T,最终函数返回的类型也是T类型的数组接口
调用的时候传入类型T为number类型。number类型是不存在属性length的
咱们调用他的toFixed方法是能够的。这个就是泛型的简单使用
const getArray = <T>(value: T, times: number = 5): T[] =>{ return new Array(times).fill(value) } console.log(getArray<number>(123, 3).map((item) => item.toFixed()))
详细讲下泛型变量,T就是泛型变量,可是T不是固定写法,能够换成u换成k都是能够的,通常习惯性用一个大写的字母,通常T用的比较多,这样就能保证咱们指定返回类型
复杂一点的例子,用了两个泛型变量
循环输出元素的第一个值和第二个值
第一个元素是数值类型,调用length就会报错,第二个元素是字符串类型,调用toFixed也会报错
在调用getArray的方法的时候,并无明确的传入类型,若是咱们不传的话,ts编辑器也会根据咱们传入的值推断出类型
固然也能够明确的制定参数的类型
const getArray = <T, U>(param1: T, param2: U, times: number): Array<[T, U]> => { return new Array(times).fill([param1, param2]) } //console.log(getArray(1, 'a', 3)) getArray<number, string>(1, 'a', 3).forEach((item) =>{ console.log(item[0]) console.log(item[1]) })
可使用泛型定义泛型函数类型
这样调用就会报错
type GetArray = <T>(arg: T, times: number) => T[] let getArray: GetArray = (arg: any, times: number) => { return new Array(times).fill(arg) }
interface GetArray { (arg: any, times: number): any[] }
使用泛型的形式
个人电脑上没有自动变成类型别名的形式
interface GetArray { <T>(arg: T, times: number): T[] }
泛型变量还能够提到接口的最外层
interface GetArray<T> { (arg: T, times: number): T[] }
除了定义函数,还能够添加属性,只要把泛型变量放到最外层,里面全部地方均可以使用这个泛型变量
泛型约束对泛型变量的条件限制
如今想对T有个要求,不能随便传任何值,只能传带length属性的(数组、字符串、自定义的对象里面写个length属性)
这里传递的是一个数组是能够的
传入数字目前是能够的,咱们要实现传入数字让不能够。由于数字是没有length的属性的
咱们这个泛型变量加限制
interface ValueWithLength { length: number } const getArray = <T extends ValueWithLength>(arg: T, times) =>{ return new Array(times).fill(arg) } getArray([1, 2], 3) getArray(123, 3)
传入字符串就不报错, 由于字符串有length的了属性
传入一个对象手打一个length属性也是能够的
interface ValueWithLength { length: number } const getArray = <T extends ValueWithLength>(arg: T, times) =>{ return new Array(times).fill(arg) } getArray([1, 2], 3) getArray({ length: 3 }, 3)
这里就是使用extends来限制泛型变量,这就是泛型约束
定义一个对象,只能访问对象上存在的属性时就用到了
定义一个函数,传入对象和属性名称,返回对象上的这个属性名称
对这个函数提供类型的提示,让使用这个函数的人在编译阶段就意识到这个错误。这个时候就是用泛型变量
keyof是个索引类型,在后面高级类型的时候会讲到,
keyof T:能够理解为 返回T这个对象上全部的属性名构成的数组
const getProp = <T, K extends keyof T>(object: T, propName: K) => { return object[propName] } const objs = { a: 'a', b: 'b', } getProp(objs, 'a') getProp(objs, 'c')