Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

介绍一下 TS 中的泛型【热度: 118】 #693

Open
yanlele opened this issue Apr 13, 2024 · 0 comments
Open

介绍一下 TS 中的泛型【热度: 118】 #693

yanlele opened this issue Apr 13, 2024 · 0 comments
Labels
TOP100互联网 公司标签 TypeScript TypeScript 语法部分
Milestone

Comments

@yanlele
Copy link
Member

yanlele commented Apr 13, 2024

关键词:TS 泛型

TypeScript 的泛型是一种工具,它能够使代码更加灵活,能够适配多种类型而非单一的类型。泛型可以创建可重用的组件,这些组件可以支持多种类型的数据,而不失去类型检查时的安全性。

泛型的基本概念

在 TypeScript 中, 泛型使用一个类型变量,常见的类型变量有 T,U,V 等。通过类型变量,你可以创建一个可以适应任何类型的组件(比如函数、接口或类)。类型变量像是函数或类的一个特殊参数,但这个参数是类型而非具体的值。

泛型的使用场景

  1. 函数:你可以创建一个泛型函数,该函数可以接受任意类型的参数,同时保证输入参数和返回参数类型相同:
function identity<T>(arg: T): T {
  return arg;
}

这里 T 用作类型变量,可以捕获用户提供的类型(比如 number),然后这个类型将被用于函数的参数和返回类型。

  1. 接口:使用泛型定义接口可以创建可用于多种类型的接口。
interface GenericIdentityFn<T> {
  (arg: T): T;
}

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

这里 GenericIdentityFn 接口定义了一个属性,它是一个接收 T 类型参数并返回 T 类型的函数。

  1. typetype 关键字可以用来创建类型别名,它确实支持泛型。你可以为类型别名定义泛型参数,然后在使用该类型别名时指定具体的类型。

下面是使用泛型的类型别名的例子:

// 这里定义了一个带有泛型参数 T 的类型别名
type Container<T> = {
  value: T;
};

// 可以这样使用类型别名
let numberContainer: Container<number> = { value: 1 };
let stringContainer: Container<string> = { value: "Hello" };

// 使用类型别名定义函数类型
type ReturnFunction<T> = () => T;

// 这个函数返回一个数字
let myFunction: ReturnFunction<number> = () => 42;

// 使用带有两个参数的泛型
type KeyValue<K, V> = {
  key: K;
  value: V;
};

let keyValue: KeyValue<string, number> = { key: "testKey", value: 123 };

通过使用泛型,type 可以定义灵活的类型别名,使得别名能够用于各种不同的数据类型,同时保持类型的安全性。这使得你可以在类型别名中使用泛型来捕获传递给别名的类型信息。

  1. :泛型也可以用于类定义中,使得类可以灵活地与多种类型协作。
class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
  return x + y;
};

这里,GenericNumber<T> 类具有一个类型为 T 的属性 zeroValue 和一个用两个 T 类型参数返回 T 类型的方法 add

泛型约束

有时你可能希望对泛型进行限制,只允许使用满足特定接口的类型。这称为泛型约束。

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;
}

在这里,我们约束了类型 T 必须遵从 Lengthwise 接口,确保传入的类型具有 length 属性。

泛型中使用类型参数

你还可以在泛型中使用类型参数本身。

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

let x = { a: 1, b: 2, c: 3 };

getProperty(x, "a"); // Okay
getProperty(x, "m"); // Error: Argument of type '"m"' isn't assignable to '"a" | "b" | "c"'

在这个示例中,getProperty 函数有两个参数:objkeyobj 是对象 TkeyT 中键的集合 keyof T 的成员。

通过泛型,TypeScript 允许你在保持类型安全的同时创建灵活,可适用于多种类型的组件。这样你就能够写出更加通用且易于复用的代码。

@yanlele yanlele added TOP100互联网 公司标签 TypeScript TypeScript 语法部分 labels Apr 13, 2024
@yanlele yanlele added this to the milestone Apr 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TOP100互联网 公司标签 TypeScript TypeScript 语法部分
Projects
None yet
Development

No branches or pull requests

1 participant