У меня есть следующий общий сценарий в моем коде TypeScript:
interface TopLevelInterface<A extends BottomLevelInterface<B>, B>
и реализация для BottomLevelInterface
, которая выглядит следующим образом:
class BottomLevelClass implements BottomLevelInterface<MyType>
Мой вопрос: При реализацииTopLevelInterface
Мне нужно не только передать аргумент типа для A
, который будет BottomLevelClass
, но и аргумент второго типа для B
, который в вышеприведенном примере будет MyType
.
Зачем мне нужно указывать B
, что можно легко вывести, посмотрев на аргумент типа BottomLevelClass
?
Например, при реализации TopLevelInterface
мне нужно указать следующее:
class TopLevelClass implements TopLevelInterface<ConcreteBottomLevel, MyType>
Вместо более короткой версии этого должно быть достаточно:
class TopLevelClass implements TopLevelInterface<ConcreteBottomLevel>
Зачем это нужно?Как я могу вывести аргумент второго типа, посмотрев на первый?Единственное решение, которое я придумал, - это использование infer
в TypeScript 2.8+ с назначением по умолчанию.Это решение выглядит следующим образом:
interface TopLevelInterface<A extends BottomLevelInterface<B>,
B = A extends BottomLevelInterface<infer _B> ? _B : any>
Однако я не могу правильно применить это с трехуровневой иерархией классов.В следующем StackBlitz вы можете видеть, что я не могу получить правильное ограничение типа для свойства model
из TopLevelClass
.Это должно быть выведено для типа SomeType
, но вместо этого выведено для never
.На MiddleLevelClass
он работает правильно.
https://stackblitz.com/edit/typescript-pcxnzo?file=infer-generics.ts
Может кто-нибудь объяснить проблему или лучший способ достичь желаемого результата?