首页 > 其他 > 详细

TypeScript--泛型

时间:2021-04-17 11:11:09      阅读:26      评论:0      收藏:0      [点我收藏+]

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

示例

假如我们需要一个 输入数字 => 返回数字 的函数

function echoValue(args: number): number {
    return args
}

// ?正确
echoValue(1)

// ?错误
// Argument of type ‘string‘ is not assignable to parameter of type ‘number‘.
echoValue(‘1‘)

也需要一个 输入字符串 => 返回字符串 的函数

function echoValue(args: string): string {
    return args
}

// ?正确
echoValue(‘1‘)

// ?错误
// Argument of type ‘number‘ is not assignable to parameter of type ‘string‘.
echoValue(1)

还需要一个 输入布尔值 => 返回布尔值 的函数

function echoValue(args: boolean): boolean {
    return args
}

// ?正确
echoValue(true)

// ?错误
// Argument of type ‘number‘ is not assignable to parameter of type ‘boolean‘.
echoValue(1)

可以发现以上三个函数,只是参数类型和返回类型不一致,看起来很冗余。

我们可以使用 泛型 解决这类问题。

function echoValue<T>(args: T): T {
    return args
}

// ?正确
echoValue<number>(1).toFixed(2)

// ?错误
// Property ‘length‘ does not exist on type ‘number‘.
echoValue<number>(1).length

// ?正确
echoValue<string>(‘1‘).length

// ?错误
// Property ‘toFixed‘ does not exist on type ‘string‘.
echoValue<string>(‘1‘).toFixed(2)

// ?正确
echoValue<boolean>(true)

这里用了一个 类型 T,这个 T 是一个抽象类型,只有在调用的时候才确定它的值。

多个类型参数

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

示例

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

// ?正确
swap([3, ‘three‘])

// ?正确
swap([‘three‘, 3])

泛型类型

示例:直接定义

const echoValue: <T>(args: T) => T = function<T>(args: T): T {
    return args
}

// ?正确
echoValue<number>(1).toFixed(2)

// ?错误
// Property ‘length‘ does not exist on type ‘number‘.
echoValue<number>(1).length

示例:使用类型别名

type EchoValue = <T>(args: T) => T

const echoValue: EchoValue = function<T>(args: T): T {
    return args
}

// ?正确
echoValue<string>(‘1‘).length

// ?错误
// Property ‘toFixed‘ does not exist on type ‘string‘.
echoValue<string>(‘1‘).toFixed(2)

使用接口

interface EchoValue {
    <T>(args: T): T
}

const echoValue: EchoValue = function<T>(args: T): T {
    return args
}

// ?正确
echoValue<string>(‘1‘).length

// ?错误
// Property ‘length‘ does not exist on type ‘boolean‘.
echoValue<boolean>(true).length

可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以

interface EchoValue {
   <T>(args: T): T
}

interface Person {
   name: string
   age: number
}

const echoValue: EchoValue = function<U>(args: U): U {
   return args
}

// ?正确
echoValue<Person>({name: ‘Tom‘, age: 23}).name

把泛型参数当作整个接口的一个参数,这样我们就能清楚的知道使用的具体是哪个泛型类型。

interface EchoValue<T> {
   (args: T): T
}

const echoValue: EchoValue<string> = function<T>(args: T): T {
   return args
}

// ?正确
echoValue(‘abc‘).length

// ?错误
// Argument of type ‘number‘ is not assignable to parameter of type ‘string‘.
echoValue(1)

泛型约束

我们有时在操作某值的属性时,是事先知道它具有此属性的,但是编译器不知道

function keyToValue(obj: object, key: string): any {
    return obj[key]
}

const stu = {name: ‘Tom‘, age: 23}

// ?正确
// 虽然正确,但是并没有检查 ‘stu‘ 对象是否拥有 ‘name‘ 属性
keyToValue(stu, ‘name‘)

// ??不会检查‘stu‘对象是否拥有‘gender‘属性
// undefined
keyToValue(stu, ‘gender‘)

通过泛型约束实现对这个问题的检查

function keyToValue<T, K extends keyof T>(obj: T, key: K) {
    return obj[key]
}

const stu = {name: ‘Tom‘, age: 23}

// ?正确
keyToValue(stu, ‘name‘)

// ?错误
// Argument of type ‘"gender"‘ is not assignable to parameter of type ‘"name" | "age"‘.
keyToValue(stu, ‘gender‘)

K 继承索引类型 keyof Tkeyof T 相当于一个由泛型变量 T 的属性名构成的联合类型。

TypeScript--泛型

原文:https://www.cnblogs.com/nipeiqing/p/14668919.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!