🛠️ 📦 TypeScript 泛型 - 速查表
TypeScript 中的泛型乍一看可能让人望而生畏——那些大写字母和方括号是干什么用的?😅
但别担心,这张备忘单可以帮助您揭开泛型的神秘面纱,并通过简单的例子向您展示它们的工作原理。
泛型的工作原理
泛型允许你定义一个类型变量,作为稍后提供的特定类型的占位符。这是泛型的核心优势:它允许你定义灵活、可复用的类型,而无需牺牲类型安全性。
按照惯例,字母 T 通常用于表示通用类型变量,但您可以使用任何适合您上下文的字母或描述性名称(其他常用字母包括 U、V、K)。
使用示例
下面是一些实际的例子,演示了泛型如何工作。
您可以在此TypeScript 游乐场中使用下面的示例。
泛型函数
// A generic function that works with any data type
function identity<T>(arg: T): T {
return arg;
}
// Using the generic function with different types
let num = identity<number>(42); // T is number
let str = identity<string>("Hello"); // T is string
//TS automatically infers the type so this also works:
//let num = identity(42); // T is number
//let str = identity("Hello"); // T is string
在此示例中, T 是一个类型参数,可以表示任何类型。实际类型在函数调用时确定,无论是数字、字符串还是其他类型。
这里,我们手动设置了类型,以突出 TypeScript 如何使用泛型处理不同类型的问题。不过,需要注意的是,TypeScript 通常会根据提供的参数自动推断类型。除非您要覆盖 TypeScript 的推断功能,或者处理需要显式类型注解的复杂类型,否则无需手动指定类型。
通用接口
这里,我们定义了一个接口 Pair,其中包含两个不同类型的属性。这些类型在创建实例时指定,可以是任意类型。唯一的限制是每个属性必须保持其各自的类型。
interface Pair<T, K> {
first: T;
second: K;
}
let pair: Pair<string, number> = { first: "one", second: 2 }
let anotherPair: Pair<number, string> = { first: 1, second: "second" }
let otherPair: Pair<number, number> = { first: 1, second: 2 }
泛型类型
泛型也可以应用于自定义类型。其过程类似于接口:使用占位符类型定义形状,占位符类型在使用该类型时确定。泛型强制指定类型,但不强制指定具体类型。
type Person<T, K, V> = {
name: T,
age: K,
isMarried: V
}
const person1: Person<string, number, boolean> = {
name: 'Bob',
age: 67,
isMarried: false
}
泛型类
泛型类允许您定义一个蓝图,其中数据类型灵活,仅在创建实例时定义。在此示例中,Box 类可以存储任何类型的内容(例如,字符串、数字或任何其他类型)。
class Box<T> {
content: T
constructor(content: T){
this.content = content
}
getContent(): T {
return this.content
}
}
const letterBox = new Box('a')
const numberBox = new Box(1)
约束
泛型还支持约束,允许您限制可使用的类型。例如,如果您只想支持具有长度属性的类型,则可以使用 extends 关键字强制执行此约束。它将泛型类型变量限制为特定类型或接口的子类型。这确保了泛型类型必须具有某些属性或结构。
type LengthType = {length: number}
function getLength<T extends LengthType>(args: T){
return args.length
}
getLength('abc')
getLength([1, 2])
//this doesn't work:
//getLength(2)
//getLength({"a": "b"})
实用程序类型
TypeScript 中的实用类型使用泛型来创建灵活且可复用的类型转换。它们通过提供内置操作来简化现有类型的使用。
interface User {
name: string;
age: number;
location: string;
}
//makes all properties optional
const partialUser: Partial<User> = {name: 'Alice'}
//allows to omit properties: here the name property is omitted
const omitUser: Omit<User, 'name'> = {location: 'Berlin', age: 33}
我希望这有帮助!
如有任何疑问,请随时联系我!您也可以在Github、LinkedIn和Instagram上找到我。
文章来源:https://dev.to/audreyk/typescript-generics-a-cheat-sheet-1a89