TypeScript泛型解释--泛型就是给类型加个参数

结合基础用法,按场景梳理 TS 泛型完整语法,搭配示例,由浅入深。

一、基础语法格式

泛型通过尖括号 <> 声明类型参数 ,常规命名:T(Type)、UVK(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 原生)

项目高频使用,语法统一为 工具类型<类型>

  1. Partial<T>:将 T 所有属性变为可选
  2. Required<T>:将 T 所有属性变为必选
  3. Readonly<T>:所有属性变为只读
  4. Pick<T, K>:从 T 中挑选 K 组成新类型
  5. Omit<T, K>:从 T 中剔除 K 组成新类型
  6. Exclude<T, U>:从 T 中排除 U 类型
  7. 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 }

八、精简语法总结

  1. 基础声明<T> 单个泛型,<T,U> 多个泛型
  2. 类型约束<T extends 类型> 限制泛型范围
  3. 默认类型<T = 类型> 给泛型设置默认值
  4. 使用场景:函数、接口、类、类型别名都可加泛型
  5. 核心优势 :替代 any,代码复用 + 完整类型检查
相关推荐
晓杰'9 小时前
从0到1实现Balatro游戏后端(4):玩家手牌操作(出牌 / 弃牌 / 补牌)与状态流转设计
后端·websocket·typescript·node.js·状态模式·项目实战·nestjs
晓说前端1 天前
第一篇:为什么学TypeScript?—— 优势、场景与环境搭建
javascript·ubuntu·typescript
妖孽白YoonA1 天前
xlt-token 1.1:给 NestJS 补上 Sa-Token 式鉴权能力
typescript·nestjs
xUxIAOrUIII1 天前
Dive into Claude Code 系列文章 - Part One
人工智能·ai·typescript
Shiy_1 天前
用 TypeScript 验证三门问题:为什么换门胜率是 2/3?
算法·typescript
kkoral2 天前
Vue3 图片标框功能实现方案
前端·vue.js·vscode·typescript
森G2 天前
TypeScript 基础类型
开发语言·typescript
烛阴2 天前
用 MCP 调教 AI 代理:让 Cocos Creator 3.8.8 核心逻辑一键全自动生成
typescript·cocos creator
Rain5093 天前
mini-cc 技术栈:跟着 Claude Code 先选 TypeScript + React + Ink
前端·javascript·react.js·typescript·node.js·ai编程