结合基础用法,按场景梳理 TS 泛型完整语法,搭配示例,由浅入深。
一、基础语法格式
泛型通过尖括号 <> 声明类型参数 ,常规命名:T(Type)、U、V、K(Key)、V(Value)、E(Element)。 基础结构:
ts
// 声明:<类型参数>
函数/类/接口 <T> (参数): 返回值
二、函数中的泛型(最常用)
1. 单个泛型参数
ts
// 定义泛型函数
function fn<T>(arg: T): T {
return arg;
}
// 调用方式1:自动类型推断(推荐)
fn(123); // T = number
fn("hello"); // T = string
// 调用方式2:手动指定类型
fn<number>(456);
fn<string>("ts");
2. 多个泛型参数
多个参数用逗号分隔 <T, U>
ts
function swap<T, U>(a: T, b: U): [T, U] {
return [a, b];
}
// 使用
swap(100, "abc"); // [number, string]
3. 泛型配合数组
ts
// 接收 T 类型的数组,返回 T 类型
function getFirst<T>(arr: T[]): T {
return arr[0];
}
getFirst([1,2,3]); // number
三、泛型约束(extends)
默认泛型 T 可以是任意类型,extends 用来限制类型范围 。 语法:T extends 目标类型
1. 约束为拥有某属性
要求传入的类型必须包含指定字段
ts
// 约束:T 必须有 length 属性
function getLen<T extends { length: number }>(arg: T): number {
return arg.length;
}
getLen("hello"); // 字符串有 length ✅
getLen([1,2,3]); // 数组有 length ✅
// getLen(123); // 数字无 length ❌ 报错
2. 约束为接口/自定义类型
ts
interface User {
id: number
}
// T 必须是 User 或 User 的子类型
function printUser<T extends User>(u: T) {
console.log(u.id);
}
3. 泛型之间互相约束
ts
// K 必须是 T 的属性名(键名约束)
function getProp<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const obj = { name: "张三", age: 20 };
getProp(obj, "name"); // ✅
// getProp(obj, "gender"); // ❌ 不存在该键
四、接口 + 泛型
让接口适配多种类型,常用于通用数据结构、容器 。 语法:interface 名称<T> {}
ts
// 通用返回结果接口
interface Result<T> {
code: number
data: T // data 类型由外部传入
msg: string
}
// 使用:指定 data 为 string 类型
const res1: Result<string> = {
code: 200,
data: "请求成功",
msg: "ok"
};
// 使用:指定 data 为数组
const res2: Result<number[]> = {
code: 200,
data: [1,2,3],
msg: "ok"
};
五、类 + 泛型
给类添加泛型,打造通用工具类/容器类 。 语法:class 类名<T> {}
ts
class Container<T> {
value: T;
constructor(val: T) {
this.value = val;
}
getVal(): T {
return this.value;
}
}
// 实例化时指定类型
const c1 = new Container<number>(10);
const c2 = new Container<string>("ts");
六、默认泛型类型
给泛型设置默认值 ,不手动传类型时自动使用默认。 语法:<T = 默认类型>
ts
// T 默认是 string
function defFn<T = string>(arg: T): T {
return arg;
}
defFn(); // 不传参,T = string
defFn(999); // 手动推导为 number
defFn<number>(1); // 手动指定
接口/类也支持默认泛型:
ts
interface Data<T = any> {
content: T
}
七、常用内置泛型工具类型(TS 原生)
项目高频使用,语法统一为 工具类型<类型>:
Partial<T>:将 T 所有属性变为可选Required<T>:将 T 所有属性变为必选Readonly<T>:所有属性变为只读Pick<T, K>:从 T 中挑选 K 组成新类型Omit<T, K>:从 T 中剔除 K 组成新类型Exclude<T, U>:从 T 中排除 U 类型Extract<T, U>:提取 T 和 U 的交集类型
示例:
ts
interface Person {
name: string
age: number
}
type P1 = Partial<Person>; // { name?: string; age?: number }
type P2 = Pick<Person, "name">; // { name: string }
八、精简语法总结
- 基础声明 :
<T>单个泛型,<T,U>多个泛型 - 类型约束 :
<T extends 类型>限制泛型范围 - 默认类型 :
<T = 类型>给泛型设置默认值 - 使用场景:函数、接口、类、类型别名都可加泛型
- 核心优势 :替代
any,代码复用 + 完整类型检查