如何让TypeScript在此处强制使用默认泛型参数类型?
TypeScript类方法泛型默认值的类型校验问题
问题代码
const EventKeys = { openItem: 'openItem', changeActiveItem: 'changeActiveItem', selectionToggled: 'selectionToggled', } as const type EventKeys = keyof typeof EventKeys class Test<Evmt>{ subscribe<CurrentEeventKey = Evmt>(arg:CurrentEeventKey){ // 函数内部类型推断正常 console.log(arg) return arg // ^? } } const t1 = new Test<EventKeys> // ^?const t1: Test<"openItem" | "changeActiveItem" | "selectionToggled"> const abc = t1.subscribe('11223') // 此处应该报错,但实际没有——不传泛型参数时未校验参数类型 // ^? const abc: "11223" t1.subscribe<'11223'>('11223') // 此处符合预期,显式传入泛型参数时允许使用该类型
需求
subscribe方法默认使用类构造时传入的泛型类型,无需重复定义;- 调用时显式传入泛型参数,方法则使用该传入的类型。
解决方案
方案1:泛型约束+默认值调整
通过调整泛型约束,让TypeScript在不显式指定泛型时,优先校验参数是否符合类的泛型类型:
const EventKeys = { openItem: 'openItem', changeActiveItem: 'changeActiveItem', selectionToggled: 'selectionToggled', } as const type EventKeys = keyof typeof EventKeys class Test<Evmt> { subscribe<CurrentEventKey extends Evmt | unknown = Evmt>(arg: CurrentEventKey): CurrentEventKey { console.log(arg) return arg } } const t1 = new Test<EventKeys>() // 现在会触发类型错误:"11223" 不符合 EventKeys 类型 const abc = t1.subscribe('11223') // 显式指定泛型参数,正常通过 t1.subscribe<'11223'>('11223')
方案2:函数重载(更清晰)
通过重载明确区分两种调用场景,逻辑更直观:
const EventKeys = { openItem: 'openItem', changeActiveItem: 'changeActiveItem', selectionToggled: 'selectionToggled', } as const type EventKeys = keyof typeof EventKeys class Test<Evmt> { // 重载1:不传泛型参数时,参数必须符合类的泛型类型 subscribe(arg: Evmt): Evmt; // 重载2:显式传入泛型参数时,使用传入的类型 subscribe<CurrentEventKey>(arg: CurrentEventKey): CurrentEventKey; // 通用实现 subscribe(arg: unknown) { console.log(arg) return arg } } const t1 = new Test<EventKeys>() // 触发类型错误,符合预期 const abc = t1.subscribe('11223') // 显式指定泛型,正常通过 t1.subscribe<'11223'>('11223')
说明
- 方案1利用泛型约束
Evmt | unknown,在不显式指定泛型时,TypeScript会尝试将参数类型与Evmt匹配,不匹配则报错;显式指定时允许任意类型。 - 方案2通过重载明确划分两种调用逻辑,代码可读性更强,适合复杂场景。
内容的提问来源于stack exchange,提问作者Ishank Sharma
相关产品推荐
相关产品推荐

