TypeScript默认类型参数未校验对象属性,为何未报错?
为什么泛型函数指定默认类型参数后,传入不符合默认类型的参数没触发错误?
我定义了HiddenField类型,要求对象必须同时拥有value和hiddenValue属性。但给泛型函数submitForm指定默认类型参数为HiddenField后,传入缺失hiddenValue的对象时,TypeScript没有报错,这是为什么?这属于Bug吗?
type HiddenField = { value: string, hiddenValue: string }; function submitForm<T = HiddenField>(fields: T[]) { fields.forEach((field, _) => { console.log(field) }); } // 执行此函数时没有任何错误或警告 submitForm([ { value: 'Taro' }, { value: 'YAMADA' }, ])
依赖包信息
{ "devDependencies": { "ts-node": "^10.9.2", "typescript": "^5.6.3" } }
Node 版本
% node -v v23.2.0 % npm -v 10.9.0
这不是Bug,是TypeScript泛型默认参数的正常行为。
泛型默认参数T = HiddenField的作用是:当你不主动指定泛型参数时,TypeScript会用HiddenField作为T的默认类型,但如果传入的参数能推导出其他类型,TypeScript会优先使用推导出来的类型。
在你的代码里,传入的数组元素只有value属性,TypeScript会自动推导出T的类型为{ value: string },完全覆盖了默认的HiddenField类型。所以编译器不会报错,因为它认为你是有意传入这种类型的参数。
如果想要强制要求传入的参数必须符合HiddenField类型,有两种解决方式:
方式1:移除泛型,直接用HiddenField[]作为参数类型
function submitForm(fields: HiddenField[]) { fields.forEach((field, _) => { console.log(field) }); }
这样只要传入的对象缺少hiddenValue,就会直接触发类型错误。
方式2:让泛型T继承HiddenField
如果需要保留泛型的灵活性,但又要确保参数至少符合HiddenField的结构,可以这样写:
function submitForm<T extends HiddenField>(fields: T[]) { fields.forEach((field, _) => { console.log(field) }); }
此时T必须是HiddenField的子类型,传入缺少hiddenValue的对象时,编译器就会报错。
内容的提问来源于stack exchange,提问作者akinoguchi
相关产品推荐
相关产品推荐

