泛型

有时,书写某个函数是,会丢失一些信息(很多位置的类型应该保持一直或有关联的信息)

泛型:是指附属于函数,类,接口,类型别名之上的类型。

泛型相当于是一个类型变量,在定义是,无法预先知道具体的类型,可以用该变量来替代,只有到调用的时候,才能确它的类型。

很多时候,TS会只能的根据传递的参数,推到出泛型的具体类型。

在函数中使用泛型

在函数名之后写上<泛型名称>

  1. function take<T>(arr : T[], n : number) : T[]{
  2. if(n > arr.length){
  3. return arr;
  4. }
  5. const newArr : T[] = []; // 默认值
  6. for(let i = 0; i < n ; i ++){
  7. newArr.push(arr[i]);
  8. }
  9. return newArr;
  10. }
  11. const result = take<number>([1,2,1,2,3,8],2)

如何在类型别名,接口,类中使用泛型。

直接在名称后面写上<泛型名称>

类型别名

  1. type callback<T> = (n : T, i : number) => boolean;
  2. function fillter<T>(arr : T[], callback : callback<T> ) : T[]{
  3. let newArr : T[] = [];
  4. arr.forEach( (n , i) => {
  5. if(callback(n , i)){
  6. newArr.push(n);
  7. }
  8. } );
  9. return newArr;
  10. }
  11. let result = fillter([1,2,3,4,5,7,8 ], n => n % 2 !== 0 );
  12. console.log(result);

接口

  1. interface callback<T> {
  2. (n : T , i : number) : boolean;
  3. }
  4. function fillter<T>(arr : T[], callback : callback<T>) : T[]{
  5. const newArr : T[] = [];
  6. arr.forEach((item, i) => {
  7. if(callback(item, i)){
  8. newArr.push(item);
  9. }
  10. })
  11. return newArr;
  12. }
  13. let result = fillter([1,2,3,4,5,7,8 ], n => n % 2 !== 0 );
  14. console.log(result);

类中使用

  1. export class ArrayHelp<T>{
  2. take<T>( arr : T[] , n : number ) : T[]{
  3. if(n > arr.length){
  4. return arr;
  5. }
  6. const newArr : T[] = [];
  7. for(let i = 0 ; i < n ; i ++){
  8. newArr.push(arr[i]);
  9. }
  10. return newArr;
  11. }
  12. private getRandom(min , max){
  13. const dec = max - min;
  14. return Math.floor( Math.random() * dec + min );
  15. }
  16. shuffle<T>(arr : T[]){
  17. for(let i = 0 ; i < arr.length ; i++){
  18. const targetIndex = this.getRandom(0, arr.length);
  19. let temp = arr[i];
  20. arr[i] = arr[targetIndex];
  21. arr[targetIndex] = temp;
  22. }
  23. return arr;
  24. }
  25. }

泛型的约束

比如说我们想给某一端文本的首字母都改为大写,然后我们则使用泛型的时候有时候是无法确定具体类型的,则我们要需要一个约束来,告知这个方法,具有该属性。

  1. interface IsName {
  2. name : string,
  3. }
  4. function nameToUpperCase<T extends IsName>(obj : T) : T{
  5. if(obj.name.length == 0){
  6. return obj;
  7. } else {
  8. obj.name = obj.name
  9. .split(" ")
  10. .map((item) => {
  11. return item[0].toUpperCase() + item.substr(1);
  12. }).join(" ");
  13. }
  14. return obj;
  15. }
  16. const o = {
  17. name : "a yu wei",
  18. age : 22,
  19. }
  20. let obj = nameToUpperCase(o);
  21. console.log(obj)

多泛型

  1. // [1,2,3] + ['a','b','c'] = [1,'a',2,'b',3,'c'];
  2. function mixinArray<T , K>(arr : T[], arr1 : K[]) : (T | K)[] {
  3. if(arr.length !== arr1.length){
  4. throw new Error("两个数组长度不等");
  5. }
  6. let result : ( T | K)[] = [];
  7. for(let i = 0 ; i < arr.length ; i ++){
  8. result.push(arr[i]);
  9. result.push(arr1[i]);
  10. }
  11. return result;
  12. }
  13. let arr = mixinArray([1,2,3] , ['a','b','c'])
  14. console.log(arr);