TypeScript 泛型约束与默认参数
泛型约束与默认参数让泛型更安全、更易用,下面梳理核心用法。
泛型约束
使用 extends 约束泛型必须满足的条件:
约束具有某属性
TypeScript
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(value: T): void {
console.log(value.length);
}
logLength("hello"); // ✅ string 有 length
logLength([1, 2, 3]); // ✅ 数组有 length
// logLength(42); // ❌ number 没有 length
约束键名
TypeScript
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 1, name: "Alice" };
getProperty(user, "name"); // ✅
// getProperty(user, "age"); // ❌ "age" 不在 keyof User 中
约束为类或构造函数
TypeScript
function createInstance<T>(ctor: new () => T): T {
return new ctor();
}
class HttpClient {
get(url: string) { return fetch(url); }
}
const client = createInstance(HttpClient);
client.get("/api");
多重约束
TypeScript
interface Serializable {
toJson(): string;
}
interface Identifiable {
id: string;
}
function serializeEntity<T extends Serializable & Identifiable>(entity: T): string {
return `ID: ${entity.id}, JSON: ${entity.toJson()}`;
}
泛型默认参数
为泛型参数指定默认类型,简化调用:
TypeScript
interface PaginationResult<T = any> {
items: T[];
total: number;
page: number;
pageSize: number;
}
// 不指定类型时使用默认值 any
const result: PaginationResult = {
items: [1, 2, 3],
total: 100,
page: 1,
pageSize: 10
};
// 指定类型
interface User { id: string; name: string; }
const userResult: PaginationResult<User> = {
items: [{ id: "1", name: "Alice" }],
total: 1,
page: 1,
pageSize: 10
};
泛型函数默认参数
TypeScript
function parseJSON<T = unknown>(str: string): T {
return JSON.parse(str) as T;
}
const data1 = parseJSON('{"name": "Alice"}'); // T 为 unknown
const data2 = parseJSON<User>('{"id": "1"}'); // T 为 User
默认参数与约束结合
TypeScript
type ApiResponse<T extends object = { id: string }> = {
code: number;
data: T;
};
const res1: ApiResponse = { code: 0, data: { id: "1" } };
const res2: ApiResponse<{ name: string }> = { code: 0, data: { name: "Alice" } };
要点总结
extends约束泛型必须具备的属性/方法/键名keyof T获取对象所有键名的联合类型,常用于约束键名范围- 泛型默认参数用
T = 默认类型简化调用方使用 - 约束与默认参数可结合使用,兼顾安全与便利
- 约束在编译期确保类型安全,避免运行时异常
📝 发现内容有误?点击此处直接编辑