Узкий контейнер дженерика c дженериком - PullRequest
0 голосов
/ 28 мая 2020

Если у меня есть общий c контейнер, подобный этому

export interface A {
 type: 'A',
 value: string
}

export interface B {
 type: 'B',
 value: number
}

export interface Container<T> {
  data: T
}

export type ContainerOfAB = Container<A | B>

Можно ли сузить тип ContainerOfAB по значению его объекта данных? Например:

export interface A {
 type: 'A',
 value: string
}

export interface B {
 type: 'B',
 value: number
}

export interface Container<T> {
  data: T
}

export type ContainerOfAB = Container<A | B>

export function detect(item: ContainerOfAB) {
  switch(item.data.type) {
    case 'A':
      takesGenericA(item) // fails
      break;
     case 'B':
      takesGenericB(item) // fails
      break;
  }
}

function takesGenericA(e: Container<A>) {

}

function takesGenericB(e: Container<B>) {

}

Кажется, что он не может сузить внутреннее значение контейнера настолько, чтобы передать его другому методу, даже если переключатель работает?

Этот пример дает следующую ошибку на любой из вызовов суженного типа

Argument of type 'ContainerOfAB' is not assignable to parameter of type 'Container<B>'.
  Type 'A | B' is not assignable to type 'B'.
    Type 'A' is not assignable to type 'B'.
      Types of property 'type' are incompatible.
        Type '"A"' is not assignable to type '"B"'.(2345)

Вот площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...