typescript---泛型

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性
泛型T作用域只限于函数内部使用

  1. 泛型函数
  • 首先,我们来实现一个函数 createArray,它可以创建一个指定长度的数组,同时将每一项都填充一个默认值
function createArray(length: number, value: any): Array<any> {
    let result: any = [];
    for(let i=0;i<length;i++){
        result[i] = value;
    }
    return result;
}
let result = createArray(3,'x');
console.log(result);

使用泛型后

function createArray<T>(length: number, value: T): Array<T> {  //这样,就约束了返回数组的类型
        let result: T[] = [];
        for(let i=0;i<length;i++){
            result[i] = value;
        }
        return result;
}
let arr = createArray<number>(3, 5);  
let arr = createArray<number>(3, "a");
  1. 泛型类
  • 类数组(Array-like Object)不是数组类型,比如 arguments
    class Person<T> {  // T的作用域是整个类
        private list: T[] = [];
        add(value: T) {
            this.list.push(value);
        }
        getMax() {
            let result: T = this.list[0];
            for(let i =1;i<this.list.length;i++){
                if(this.list[i] > result){
                    result = this.list[i];
                }
            }
            return result;
        }
    }

3.泛型接口

  • 泛型接口可以用来约束函数
interface Caculate {
  <T>(a: T, b: T): T
}
const add: Caculate = function <T>(a: T, b: T): T{
    return a
}
add<number>(3,5)
add<number>(3,"5") //报错,此处T是number,“5”是字符串
  1. 多个类型参数
function swap<A, B>(touple: [A, B]): [B, A] { //touple是元组
    return [touple[1], touple[0]]
}
let swapped = swap<string,number>(['a',1]);
console.log(swapped);
console.log(swapped[0].toFixed(2));
console.log(swapped[1].length);
  1. 默认泛型类型
function createArray3<T=number>(length: number, value: T): Array<T> {
  let result: T[] = [];
  for (let i = 0; i < length; i++) {
    result[i] = value;
  }
  return result;
}
let result2 = createArray3(3,3);
let result3 = createArray3<string>(3,'3');
  1. 泛型约束
  • 在函数中使用泛型的时候,由于预先并不知道泛型的类型,所以不能随意访问相应类型的属性或方法。
function logger<T>(val: T) {
    console.log(val.length); //直接访问会报错,因为T类型未知,不一定有length属性
}
interface LengthWise {
    length: number
}

//可以让泛型继承一个接口
function logger2<T extends LengthWise>(val: T) {
    console.log(val.length)
}
logger2('lc');  // 2
logger2({length: 5});  //5
logger2(1); //报错,1或者new Number(1)都没有length属性
  1. 泛型接口
  • 定义接口的时候也可以指定泛型
interface Cart<T>{
  list:T[]
}
let cart:Cart<{name:string,price:number}> = {
  list:[{name:'zhufeng',price:10}]
}
console.log(cart.list[0].name,cart.list[0].price);
  1. 泛型类型别名
  • 泛型类型别名可以表达更复杂的类型
type Cart<T> = {list:T[]} | T[];  //联合类型
let c1:Cart<string> = {list:['1']};
let c2:Cart<number> = [1];
  1. 泛型接口 vs 泛型类型别名
  • 接口创建了一个新的名字,它可以在其他任意地方被调用。而类型别名并不创建新的名字,例如报错信息就不会使用别名
  • 类型别名不能被 extends和 implements,这时我们应该尽量使用接口代替类型别名
  • 当我们需要使用联合类型或者元组类型的时候,类型别名会更合适
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能...
    2o壹9阅读 3,788评论 0 48
  • 泛型 软件工程中,我们不仅要创建定义良好且一致的 API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,...
    罗彬727阅读 3,823评论 0 0
  • 泛型 泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种...
    一瓣山河阅读 2,910评论 0 1
  • 前言:泛型的英译generics [dʒɪˈnɛrɪks] 泛型;;范型;通用类型; 通用类型这四个字就是泛型的真...
    CondorHero阅读 1,765评论 0 1
  • 泛型 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同...
    Jack_Peng阅读 2,778评论 0 1

友情链接更多精彩内容