骆熙华 发表于 2025-9-12 21:15:18

如何在Typescript中使用泛型约束

在 TypeScript 中,泛型约束(Generic Constraints)用于限制泛型可以接受的类型范围,确保泛型参数不是只能接受任意类型,而是只能接受满足特定条件的类型。这既保留了泛型的灵活性,又增强了类型安全性。
为什么需要泛型约束?

默认情况下,泛型可以是任何类型,但有时你需要访问类型的特定属性或方法。如果不加以约束,TypeScript 无法保证这些属性 / 方法存在,会导致类型错误。例如,尝试访问泛型参数的 length 属性:
// 错误示例:TypeScript 无法确定 T 有 length 属性
function getLength<T>(arg: T): number {
return arg.length; // 报错:Property 'length' does not exist on type 'T'
}这时就需要泛型约束来指定 T 必须包含 length 属性。
如何使用泛型约束?

通过 extends 关键字可以实现泛型约束,语法为 。
1. 基础约束:限制为特定结构

最常见的约束是要求泛型必须包含某些属性或方法。例如,约束 T 必须有 length 属性:
// 定义一个接口作为约束条件
interface HasLength {
length: number;
}

// 使用 extends 约束 T 必须符合 HasLength 结构
function getLength<T extends HasLength>(arg: T): number {
return arg.length; // 现在可以安全访问 length 了
}

// 正确用法:字符串、数组等有 length 属性的类型
getLength("hello"); // 5(字符串有 length)
getLength(); // 3(数组有 length)

// 错误用法:数字没有 length 属性
getLength(123); // 报错:Argument of type 'number' is not assignable to parameter of type 'HasLength'2. 约束为另一个类型的子类型

可以约束泛型必须是另一个类型的子类型,例如约束 T 必须是 User 类型的子类型:
interface User {
id: number;
name: string;
}

// 约束 T 必须是 User 的子类型(即必须包含 id 和 name)
function getUserInfo<T extends User>(user: T): string {
return `ID: ${user.id}, Name: ${user.name}`;
}

// 正确:符合 User 结构
getUserInfo({ id: 1, name: "Alice" });

// 正确:扩展了 User 结构(允许额外属性)
getUserInfo({ id: 2, name: "Bob", age: 30 });

// 错误:缺少 name 属性,不符合 User 结构
getUserInfo({ id: 3 }); // 报错:Property 'name' is missing3. 约束为 keyof 另一个类型(键约束)

使用 keyof 可以约束泛型必须是某个对象类型的键,常用于安全地访问对象属性:
// 约束 K 必须是 T 的键(keyof T 返回 T 所有键的联合类型)
function getProperty<T, K extends keyof T>(obj: T, key: K): T {
return obj; // 安全访问 obj 的属性
}

const person = { name: "Alice", age: 25 };

// 正确:key 是 person 的有效键
getProperty(person, "name"); // "Alice"(类型:string)
getProperty(person, "age"); // 25(类型:number)

// 错误:key 不是 person 的键
getProperty(person, "height"); // 报错:Argument of type '"height"' is not assignable to parameter of type '"name" | "age"'4. 多个约束(交叉类型)

如果需要同时满足多个约束,可以使用交叉类型(&)组合多个条件:
interface HasLength {
length: number;
}

interface HasName {
name: string;
}

// 约束 T 必须同时满足 HasLength 和 HasName
function getInfo<T extends HasLength & HasName>(obj: T): string {
return `Name: ${obj.name}, Length: ${obj.length}`;
}

// 正确:同时有 name 和 length
getInfo({ name: "Test", length: 10 });

// 错误:缺少 length
getInfo({ name: "Test" }); // 报错:Property 'length' is missing总结

泛型约束的核心是通过 extends 关键字限制泛型的范围,常见用法包括:  1.约束为包含特定属性 / 方法的结构
  2.约束为另一个类型的子类型
  3.结合 keyof 约束为对象的键
  4.多个约束的组合(交叉类型)
通过泛型约束,既能保留泛型的灵活性,又能确保代码在编译时的类型安全,避免运行时错误。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

空娅芬 发表于 2025-10-9 06:42:33

这个好,看起来很实用

鞍汉 发表于 2025-10-14 03:22:25

这个好,看起来很实用

肿抢 发表于 2025-11-11 05:35:40

谢谢楼主提供!

科元料 发表于 2025-12-17 14:29:46

懂技术并乐意极积无私分享的人越来越少。珍惜

缑娅瑛 发表于 2025-12-22 06:26:55

新版吗?好像是停更了吧。

处匈跑 发表于 2025-12-23 01:47:24

谢谢分享,辛苦了

咫噎 发表于 2026-1-8 22:49:56

很好很强大我过来先占个楼 待编辑

嶝扁 发表于 2026-1-15 16:30:36

谢谢楼主提供!

聊账 发表于 2026-1-21 03:52:21

谢谢楼主提供!

采序 发表于 2026-1-22 12:46:51

懂技术并乐意极积无私分享的人越来越少。珍惜

吁寂 发表于 2026-1-24 09:42:05

过来提前占个楼

钿稳铆 发表于 2026-1-25 08:31:01

这个好,看起来很实用

莠畅缕 发表于 2026-1-27 06:19:32

这个有用。

洪势 发表于 2026-2-3 05:48:01

分享、互助 让互联网精神温暖你我

顶豌 发表于 2026-2-3 07:52:39

感谢,下载保存了

喙审 发表于 2026-2-3 09:49:46

感谢分享,学习下。

司马黛 发表于 2026-2-7 05:28:53

感谢发布原创作品,程序园因你更精彩

些耨努 发表于 2026-2-7 08:34:39

不错,里面软件多更新就更好了

洪势 发表于 2026-2-8 11:12:41

过来提前占个楼
页: [1] 2
查看完整版本: 如何在Typescript中使用泛型约束