TypeScript中泛型Data extends {}为何无法将{}作为默认参数赋值?
问题核心原因
Data extends {} 不是说Data类型等于{},而是表示Data必须是满足空对象结构的任意子类型。
举个实际的调用场景你就懂了:
// 这个调用完全符合泛型约束,因为{id: number}是{}的子类型 fn<{id: number}>()
这时候按照你的函数定义,没传参数时data的默认值是{},但此时Data的实际类型是{id: number},{}显然没有必填的id属性,类型不匹配,这就是TS报错的原因。
TS的报错提示已经点明了逻辑:
无法将类型“{}”分配给类型“Data”。“{}”可以分配给“Data”类型的约束条件,但“Data”可能被实例化为约束条件“{}”的其他子类型。ts(2322)
可行的解决方案
- 如果你确定业务场景中,用户不传入参数时默认用
{}是合理的,只需要加个类型断言即可:
function fn<Data extends {}>(data: Data = {} as Data) { }
注意这种写法的前提是:如果调用方手动指定了带必填属性的Data泛型,就必须主动传入符合类型的data参数,否则运行时会出现属性缺失的问题。
- 更稳妥的写法是给泛型加上默认类型,和默认值对应:
function fn<Data extends {} = {}>(data: Data = {} as Data) { }
这样当用户没有手动指定Data类型时,默认的Data就是{},类型完全匹配,不会有隐藏风险。
内容的提问来源于stack exchange,提问作者Jacob Weisenburger
相关产品推荐
相关产品推荐

