typescript中泛型约束和默认类型可同时使用,需先写约束(extends)再写默认值(=),且默认类型必须满足约束条件。

TypeScript 中泛型约束和默认类型可以同时使用,但要注意它们的语法顺序和作用逻辑:约束(extends)定义类型边界,而默认类型(=)只在调用时未显式传入类型参数时生效。两者不冲突,但默认类型必须满足约束条件,否则会报错。
泛型约束 + 默认类型的写法
在声明泛型时,先写约束,再写默认值。语法格式为:<t extends someconstraint="DefaultType"></t>。TypeScript 要求默认类型必须是约束范围内的子类型,否则编译失败。
- ✅ 正确示例:接口要求
T有length属性,默认给string
interface HasLength { length: number }
function logLength
return val.length;
}
// 调用时不传类型参数,自动用 string
logLength("hello"); // ✅ OK
logLength([1, 2, 3]); // ✅ OK(显式传入 number[])
logLength(42); // ❌ 报错:number 不满足 HasLength 约束
- ❌ 错误示例:默认类型违反约束
interface User { name: string }
// 错误:{} 不满足 User 约束(缺少 name)
function getUser
函数中常见组合用法
实际开发中,常把约束用于保证操作安全,再配默认类型简化高频调用。比如处理可索引对象的键访问:
- 用
keyof T约束键类型,确保只传对象合法属性名 - 用默认类型
string或any(谨慎)降低调用门槛
function getProperty
return obj[key];
}
const user = { id: 1, name: "Alice" };
getProperty(user, "name"); // ✅ 自动推断 T=User, K="name"
getProperty(user, "age"); // ❌ 编译报错:'age' 不在 user 的键中
泛型接口/类中的默认+约束
接口和类也支持类似写法,适用于配置型结构或通用容器:
- 接口泛型默认值需满足约束,且调用时可省略类型参数
- 类构造器不参与泛型推导,但实例方法可复用相同约束逻辑
interface ApiResponse
code: number;
data: T;
}
const res1: ApiResponse = { code: 200, data: { status: "ok" } }; // ✅ 使用默认类型
const res2: ApiResponse = { code: 200, data: { id: 123 } }; // ✅ 显式覆盖
注意事项
几个容易踩坑的点:
- 默认类型不能是
any或unknown,除非约束本身允许(如T extends any,但无意义) - 多个泛型参数之间可相互约束,但默认值仍须独立满足各自约束
- 类型推导优先级:实参类型 → 显式传入类型参数 → 默认类型(仅当未传且推导不出时启用)










