TypeScript中能否基于泛型参数类型对整个interface进行重载?
解决方案
TypeScript 不支持你示例中的泛型接口重载写法:接口合并规则要求同名接口的泛型参数列表完全一致,你写的Foo<T>、Foo<string>、Foo<number>不会被识别为不同重载,反而会抛出语法错误。
你要的效果可以通过条件类型实现,结构比单属性加条件判断清晰很多:
type Foo<T> = T extends string ? { foo(): void bar(): void } : T extends number ? { bar(): void } // 其他泛型类型对应的结构可以在这里自定义 : never
使用效果如下:
// 泛型为string时,同时有foo、bar方法 const stringFoo: Foo<string> = { foo: () => console.log('foo'), bar: () => console.log('bar') } stringFoo.foo() // 类型正常识别,无报错 stringFoo.bar() // 类型正常识别,无报错 // 泛型为number时,仅存在bar方法 const numberFoo: Foo<number> = { bar: () => console.log('bar') } numberFoo.bar() // 类型正常识别,无报错 numberFoo.foo() // 类型报错:属性“foo”不存在于类型“Foo<number>”上
如果不同泛型对应的接口有公共属性,可抽离公共部分减少冗余:
// 抽离所有类型通用的公共属性 interface BaseFoo { bar(): void } // 定义string类型独有的属性 interface StringFoo extends BaseFoo { foo(): void } type Foo<T> = T extends string ? StringFoo : BaseFoo
后续需要新增其他泛型类型的适配,直接在条件类型中新增对应分支即可,维护成本很低。
内容的提问来源于stack exchange,提问作者David Alsh
相关产品推荐
相关产品推荐

