接口与类
泛型基础
理解泛型函数、泛型接口、泛型约束
泛型基础
泛型让函数和类型可以"接受类型作为参数"。不用泛型的话,你只能写死类型(不灵活)或用 any(不安全)。泛型兼顾了灵活性和类型安全。
学完本章你将: 理解泛型函数、泛型接口、泛型约束。
问题:any 丢掉类型信息
typescript
// ❌ any —— 入参 string 出参变成 any,类型丢了
function identity(arg: any): any { return arg; }
const result = identity("hello");
// result 类型是 any!后续调用 result.toUpperCase() 没有智能提示
// ❌ 写死类型 —— 不灵活
function identityStr(arg: string): string { return arg; }
// 传 number 就得再写一个 identityNum…
泛型函数 —— 类型参数 T
泛型用一个类型变量 T 来代表"将来才会确定的类型"。调用时,TypeScript 从实参自动推断 T。
typescript
// <T> 声明了类型参数,后续的 T 都用这个类型
function identity<T>(arg: T): T {
return arg;
}
const a = identity("hello"); // T 推断为 string → a 是 string
const b = identity(42); // T 推断为 number → b 是 number
const c = identity<boolean>(true); // 手动指定 T = boolean
// 多个类型参数
function pair<T, U>(first: T, second: U): [T, U] {
return [first, second];
}
const p = pair("hello", 42); // p 是 [string, number]
💡 T 只是一个名字——你可以叫它任何东西。
<Type>、<TData>都行,但约定俗成用单个大写字母(T=Type, K=Key, V=Value)。
泛型接口 —— 定义通用结构
泛型在接口中最常见的场景:API 响应的通用包装。
typescript
// 一个接口,适配所有类型的 data
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// 使用时指定 T
type UserResponse = ApiResponse<{ name: string; age: number }>;
type ListResponse = ApiResponse<string[]>;
const resp: UserResponse = {
data: { name: "Alice", age: 25 },
status: 200,
message: "ok",
};
// resp.data.name 有智能提示 ✅
泛型约束 —— 限制 T 的类型
有时候你想让 T 有一定的能力(比如有 .length 属性)。用 extends 给 T 加约束。
typescript
// T 必须满足 HasLength(有 length 属性)
interface HasLength { length: number; }
function logLength<T extends HasLength>(arg: T): T {
console.log(arg.length); // ✅ 现在可以安全访问 .length
return arg;
}
logLength("hello"); // 5 ✅
logLength([1, 2, 3]); // 3 ✅
// logLength(42); // ❌ number 没有 length
// 约束为对象的键
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: "Alice", age: 25 };
getValue(user, "name"); // ✅ 返回 string
// getValue(user, "email"); // ❌ "email" 不存在
// 约束为对象的键 function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; }
const user = { name: "Alice", age: 25 }; console.log(getProperty(user, "name")); // "Alice" // getProperty(user, "email"); // ❌ "email" 不存在于 user
---
## 泛型默认值
```typescript
// 默认泛型参数
interface Pagination<T = string> {
data: T[];
page: number;
}
const strPage: Pagination = { data: ["a", "b"], page: 1 }; // T = string
const numPage: Pagination<number> = { data: [1, 2], page: 1 }; // T = number