美文网首页
TypeScript(三) 泛型

TypeScript(三) 泛型

作者: 梦晓半夏_d68a | 来源:发表于2022-12-24 01:18 被阅读0次

参考
参考2
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

泛型使用

function func(arg: any): any {
  return arg
}

这段代码编译不会报错,但是一个显而易见的缺陷是,它并没有准确的定义返回值的类型,而我们想要的是传入什么类型,返回值就是什么类型。

函数参数使用泛型

// <T> 相当于定义了类型T
function func<T>(arg: T): T {
  return arg
}
func(10) // 不指定泛型类型,ts进行推断
func<string>('ssss') // 指定泛型类型(建议)

type 和 interface都可以定义函数类型,也用泛型来写一下,type 这么写:

type Print = <T>(arg: T) => T
const printFn:Print = function print(arg) {
    console.log(arg)
    return arg
}

interface 这么写:

interface Iprint<T> {
    (arg: T): T
}

function print<T>(arg:T) {
    console.log(arg)
    return arg
}

const myPrint: Iprint<number> = print

默认参数
如果要给泛型加默认参数,可以这么写:

interface Iprint<T = number> {
    (arg: T): T
}

function print<T>(arg:T) {
    console.log(arg)
    return arg
}

const myPrint: Iprint = print

这样默认就是 number 类型了,怎么样,是不是感觉 T 就如同函数参数一样呢?

多个类型参数
定义泛型的时候,可以一次定义多个类型参数:

function swap<T, U>(tuple: [T, U]): [U, T] {
    return [tuple[1], tuple[0]];
}

swap<number, string>([7, 'seven']); // ['seven', 7]

上例中,我们定义了一个 swap 函数,用来交换输入的元组。

函数副作用操作

泛型不仅可以很方便地约束函数的参数类型,还可以用在函数执行副作用操作的时候。

比如我们有一个通用的异步请求方法,想根据不同的 url 请求返回不同类型的数据。

function request(url:string) {
    return fetch(url).then(res => res.json())
}

调一个获取用户信息的接口:

request('user/info').then(res =>{
    console.log(res)
})

这时候的返回结果 res 就是一个 any 类型,我们希望调用 API 都清晰的知道返回类型是什么数据结构,就可以这么做:

interface UserInfo {
    name: string
    age: number
}

function request<T>(url:string): Promise<T> {
    return fetch(url).then(res => res.json())
}

request<UserInfo>('user/info').then(res =>{
    console.log(res)
})

这样就能很舒服地拿到接口返回的数据类型,开发效率大大提高

泛型约束
在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法:

// 有参数length 属性(字符串、数组、对象key含length)
interface Inter {
  length: number
}
function func3<T extends Inter>(a: T): number {
  return a.length
}

func3('ssjsjjssj')
func3([1, 2, 3])
func3({
  length: 3,
  age: 99
})

泛型的应用场景

泛型约束类
定义一个栈,有入栈和出栈两个方法,如果想入栈和出栈的元素类型统一,就可以这么写:

class Stack<T> {
    private data: T[] = []
    push(item:T) {
        return this.data.push(item)
    }
    pop():T | undefined {
        return this.data.pop()
    }
}

在定义实例的时候写类型,比如,入栈和出栈都要是 number 类型,就这么写:

const s1 = new Stack<number>()

这样,入栈一个字符串就会报错,特别注意的是,泛型无法约束类的静态成员。

泛型约束接口
使用泛型,也可以对 interface 进行改造,让 interface 更灵活。

interface IKeyValue<T, U> {
    key: T
    value: U
}

const k1:IKeyValue<number, string> = { key: 18, value: 'lin'}
const k2:IKeyValue<string, number> = { key: 'lin', value: 18}

泛型约束函数

function func<T>(arg: T): T {
  return arg
}
func<string>('ssss') // 指定泛型类型(建议)

泛型定义数组
定义一个数组

const arr: Array<number> = [1,2,3]

相关文章

  • 03_TypeScript学习(三)

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

  • 三、TypeScript 泛型

    什么是泛型 理解:泛型就是在编译期间不确定类型(广泛之意思),在调用时,由程序员指定的泛型具体指向什么类型。泛型在...

  • TypeScript(三) 泛型

    参考[https://ts.xcatliu.com/advanced/generics.html]参考2[http...

  • 2020-11-05Typescript(2.2)

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

  • TS 泛型+装饰器

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

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

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

  • TypeScript 学习笔记4 泛型

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

  • typescript

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

  • TypeScript 泛型

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

  • TypeScript泛型

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

网友评论

      本文标题:TypeScript(三) 泛型

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