美文网首页基础前端
TypeScript ——泛型

TypeScript ——泛型

作者: CondorHero | 来源:发表于2020-02-04 01:27 被阅读0次

前言:泛型的英译generics [dʒɪˈnɛrɪks] 泛型;;范型;通用类型; 通用类型这四个字就是泛型的真谛。很多人把泛型比作组件,这是很恰当的,组件最大的优点就是可以复用,泛型可以应用在函数、类、接口上,可以像组件一样提高它们的复用性。具体能解决的一个大问题就是输入即输出。例如一个函数或一个类的方法或一个函数接口:想要传入参数类型和返回结果类型一致。最简单的实现方法是使用 any,但是这时就丧失了类型检查,所以泛型才是唯一的解决之道。

一、泛型的分类

泛型可分为三大类:

1. 函数泛型
2. 类泛型
3. 接口泛型
二、函数泛型

在前言中我们提到的一个问题,如果使用函数写出来,估计就是写几个函数,利用函数的重载来实现,如果不使用 any 的话,现在我们用函数泛型来实现如下:

function main<T>(a:T):T {
    return a;
}
console.log(main<number>(1));
console.log(main("2"));

这里,我们使用了 类型变量/泛型变量,它是一种特殊的变量,只用于表示类型而不是值。我们给 main 添加了类型变量 T(只要是大写的字母就行)。 T 帮助我们捕获用户传入的类型(比如:number),之后我们就可以使用这个类型。 之后我们再次使用了 T当做返回值类型。现在我们可以知道参数类型与返回值类型是相同的了。这允许我们跟踪函数里使用的类型的信息。这就是函数泛型。

我们有两种使用办法:

  1. 传入所有的参数,包含类型参数,使用尖括号。
main<number>(1);
  1. 用类型推论,编译器会根据传入的参数自动地帮助我们确定T的类型(推荐)
main("2")

这时得介绍泛型变量:

依然是上面这个函数,现在我们要出入字符串并需要在函数体里面打印出字符串的长度,改写为:

function main<T>(a:T):T {
    console.log(a.length);
    return a;
}
console.log(main("9876543"));

程序这时提示错误:

Property 'length' does not exist on type 'T'

使用泛型创建像 main 这样的泛型函数时,编译器要求你在函数体必须正确的使用这个通用的类型。 换句话说,你必须把这些参数当做是任意类型(或所有类型)。上面我们程序员只考虑了,字符串这一种类型,但是编辑器会帮我们考虑所有的类型,数字类型 number 就在里面,而 number 是没有 length 的,所以会报错。

现在假设我们想操作T类型的数组而不直接是T。由于我们操作的是数组,所以.length属性是应该存在的。

function main<T>(params:T[]):T[]{
    console.log(params.length);
    return params;
}
main([1,2,"3"]);

这时就没有错了,你可以认为这种写法就表示参数为数组的形式,T 后面不加方括号表示任意类型。那么如何理解这个数组式的写法,你现在就可以认为函数接受元素类型是 T 的数组,并返回元素类型是 T 的数组。这个数组式泛型还有一种写法:

function main<T>(params:Array<T>):Array<T>{
    console.log(params.length);
    return params;
}
main([1,2,"3"]);
三、类泛型
class People<T>{
    public name:T;
    constructor(name:T){
        this.name = name;
    }
};
let CH = new People("Condor Hero");
console.log(CH.name);
四、接口泛型

接口泛型分为两种。

  1. 通用型接口泛型
interface Animal<T>{
    name:T;
};
let dog:Animal<string> = { name:"旺财" };
  1. 函数接口泛型
interface Animal{
    <T>(name:T):T
};
let dog:Animal = function<T>(name:T):T {
    return name;
}
console.log(dog("旺财"));
五、泛型约束

泛型变量 T 其实一直是被约束的,只不过这里使用继承来实现的约束。

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}

现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:

loggingIdentity(3);  // Error, number doesn't have a .length property

我们需要传入符合约束类型的值,必须包含必须的 length 属性:

loggingIdentity([1]);
loggingIdentity("qwert");
loggingIdentity({length: 10, value: 3});

数组、字符串和自定义的对象都有 length ,都可以传入。

相关文章

  • 2020-11-05Typescript(2.2)

    泛型 Generics---typeScript中最难的一部分 泛型 Generics---约束泛型 泛型 Gen...

  • TS 泛型+装饰器

    typescript 中的泛型 泛型的定义泛型函数泛型类泛型接口 泛型:软件工程中,我们不仅要创建一致的定义良好的...

  • bunny笔记|TS基础(2):泛型函数、泛型约束、在泛型约束中

    01 typescript的操纵类型 02 03 04 泛型约束 05 在泛型约束中使用类型参数 06 在泛型中使...

  • 03_TypeScript学习(三)

    一. TypeScript枚举类型 二. 枚举类型的值 三. 认识泛型 四. 泛型实现类型参数化 五. 泛型的基本...

  • TypeScript 学习笔记4 泛型

    1.泛型 1.1 泛型函数 1.2 泛型类 1.3 泛型接口 Typescript从0到1-学习视频教程-培训课程...

  • typescript

    title: typescript学习tags: typescript学习 [toc] 泛型 基本使用 两种使用方...

  • TypeScript 泛型

    泛型函数 使用 数组 类 泛型约束

  • TypeScript泛型

    有时候编程还要考虑它的复用性,很多时候不需要指定它的类型,或者同样的方法逻辑 但是入参和出差的类型不同。这个时候就...

  • TypeScript(泛型)

    泛型 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同...

  • TypeScript -- 泛型

    1. 很多时候我们希望一个函数或者一个类可以支持多种数据类型,有很大的灵活性2.泛型:不预先确定的数据类型,具体的...

网友评论

    本文标题:TypeScript ——泛型

    本文链接:https://www.haomeiwen.com/subject/sfffxhtx.html