T extends U 泛型约束

最后更新:2026-10-22

T extends U 泛型约束

约束(extends)给类型参数"划定范围":<T extends HasId> 承诺"T 至少有 id: number"。约束之内可以放心访问 T 的公共成员,约束之外(传个 string 进来)编译期直接拒绝——比 any 安全,比具体类型灵活。

分组泛型
类型语法
严格模式不需要

ℹ️ 说明 编辑器将 TypeScript 转译为 JavaScript 后运行(不做类型检查);类型检查结果见示例 Output。

📝 语法

interface HasId {
  id: number;
}

function findById<T extends HasId>(items: T[], id: number): T | undefined {
  return items.find((item) => item.id === id);
}

⚙️ 参数

T extends HasId约束:实参类型必须兼容 HasId(至少含 id: number)
T | undefined返回类型保留实参的精确形状:传入什么形状的数组,就取回同样形状的元素

返回值:与未加约束的泛型一致——保留实参的精确类型;区别在于函数体内 T 的可用成员变多了。

▶ 示例

修改下面的代码,点击试一试查看转译运行结果:

输出:

Desk
未找到

(转译后运行输出;products 的元素有额外字段没关系——结构化类型只检查约束要求的成员)

💡 要点

ℹ️ 说明 约束不要求"恰好等于":{ id: 1, name: "Lamp", price: 59 } 的额外字段不影响兼容——结构化类型只检查约束要求的成员是否齐备。
💡 提示 内联约束省掉中间接口:function sumLengths<T extends { length: number }>(a: T, b: T) 直接描述"只要有 length";复杂约束才值得提接口。
⚠️ 注意 约束给的是"下限":T extends HasId 只保证 id 存在,item.name 在编译器眼里仍不存在——除非再约束 name: string。
更多案例即将上线。

📚 相关教程

❓ 常见问题

Q 约束和泛型默认值能同时用吗?
A 能且常配合:<T extends HasId = User>——不传时用默认 User,传了必须满足 HasId。默认值必须在约束范围内。
Q 怎么约束"必须是某几个字面量之一"?
A 用字面量联合:function set<K extends "light" | "dark">(theme: K)。K 会收窄到具体字面量,越界值编译报错。
Q 多个类型参数互相约束怎么写?
A 让后者引用前者:<K extends keyof T>——K 的取值范围由 T 决定,这是 keyof 模式的核心,保证键名与对象真实匹配。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏