我编写了以下代码来获取给定类/接口的“ SuperType”。
type SuperType<T> = T extends infer U ? U : never;
我知道类可以从多个类扩展,但是我希望只获得第一个。
但是,这总是返回类本身,这是有道理的,因为:
type x<T> = T extends T ? true : never; // true for any T
有没有一种方法可以编写我的SuperType<T>
类型,以便提供以下两种类型之一?
答案 0 :(得分:2)
我认为您不会找到一种方法来做到这一点[1]
条件类型对“自身”类型进行操作;关于任何给定类的基类的信息根本不会出现在类的实例类型上,因为该信息仅在声明站点用于复制特定属性并执行一些可分配性检查。
[1]我最初写的是“这是不可能的”,但我可能是错的(但我可能不是)
答案 1 :(得分:1)
与@ ryan-cavanaugh一样,我认为这是不可能的。我们可以做的是创建某种结构来记录当前类中该类的超类型。假设您可以控制基类,但事实并非如此
此解决方案依赖于Tuples in rest parameters and spread expressions的3.0功能。我试图让它在没有此功能的情况下正常工作,但是事情变得更好:
class Foo { fooMethod(): void { } }
class Boo extends ext(Foo) { barMethod(): void { } }
class Baz extends ext(Boo) { bazMethod(): void { } }
type ArgumentTypes<T> = T extends (...a: infer U) => void ? U : never;
type SuperTypes<T> = T extends { super: infer U } ? ArgumentTypes<U> : [];
function ext<T extends { new(): any; super?: (...a: any[]) => void }>(c: T): T & { super(p: T, ...a: SuperTypes<T>): void } {
return c as any;
}
type AllBaseTypesOfBaz = SuperTypes<typeof Baz> // [typeof Boo, typeof Foo]
type BaseTypeOfBaz = SuperTypes<typeof Baz>[0] // typeof Boo