TypeScript类泛型方法重写时=与extends的入参类型校验差异问题
问题原因
两个关键字的作用完全不同,导致校验逻辑差异:
=仅用于设置泛型参数的默认类型,没有任何约束效力:当调用方法未显式传入泛型时,TypeScript 会优先从入参反向推导泛型的实际类型,默认值只有在类型推导失效的场景下才会生效。你调用createTwo({bar: 'test'})时,TS 直接把$CreateRequestBody推导为{bar: string},完全不会触发默认值{foo: string}的校验,所以入参校验失效。extends用于设置泛型参数的类型上界约束:无论是否显式传入泛型、无论入参推导结果是什么,最终的泛型类型必须符合extends后定义的类型要求,因此入参自然会被严格校验。
解决方案
要同时满足「默认场景下校验入参符合类定义的请求类型」和「调用时可重写泛型类型」的需求,直接给方法泛型同时添加 extends 约束和默认值即可:
class Service< RequestBody, ResponseBody, CreateRequestBody = RequestBody, CreateResponseBody = ResponseBody, > { public createTwo< // 同时加约束和默认值 $CreateRequestBody extends CreateRequestBody = CreateRequestBody, $CreateResponseBody extends CreateResponseBody = CreateResponseBody >(body : $CreateRequestBody) : $CreateResponseBody { return null; } }
修改后效果符合预期:
- 调用时不传泛型:泛型取默认值
CreateRequestBody,同时受extends约束,入参会被严格校验,传入{bar: 'test'}会直接抛出类型错误。 - 调用时显式传入自定义泛型:只要传入的类型符合
extends定义的上界约束即可正常使用,如果业务需要支持完全重写、不限制传入的泛型类型,只需把约束上界改为unknown即可:$CreateRequestBody extends unknown = CreateRequestBody。
内容的提问来源于stack exchange,提问作者user924017
相关产品推荐
相关产品推荐

