Загрузка различаемых объединений из базы данных

#typescript #discriminated-union

#typescript #различаемое объединение

Вопрос:

У меня есть различаемое объединение, определенное следующим образом:

 enum ShapeKind {
  Square = 'sqaure',
  Rectangle = 'rectangle',
}

interface Square {
    kind: ShapeKind.Square;
    size: number;
}

interface Rectangle {
    kind: ShapeKind.Rectangle;
    width: number;
    height: number;
}

type Shape = Square | Rectangle;
  

Я хочу иметь возможность загружать их из базы данных. У меня есть метод со следующей подписью:

 getShape(kind: ShapeKind, id: string): Shape
  

При этом выполняется запрос к базе данных следующим образом и возвращается объект, соответствующий интерфейсу на основе kind поля записи:

 SELECT * FROM shapes WHERE id = ? AND kind = ? LIMIT 1
  

Если я передам, ShapeKind.Rectangle я знаю, что это должно вернуть Rectangle (или выдать ошибку «не найдено»), но на данный момент возвращаемый тип всегда Shape независимо от того, что я передаю.

Как мне заставить компилятор понять это правило?

Ответ №1:

Вы можете использовать перегрузку функции:

 function getShape(kind: ShapeKind.Rectangle, id: string): Rectangle
function getShape(kind: ShapeKind.Square, id: string): Square
function getShape(kind: ShapeKind, id: string): Shape {
  // Your query here  
  switch (kind) {
    case ShapeKind.Rectangle:
      return {
        kind: ShapeKind.Rectangle,
        width: 1,
        height: 1,
      }
    case ShapeKind.Square:
      return {
        kind: ShapeKind.Square,
        size: 1,
      }
  }
}