Свойство не существует при использовании типа объединения в машинописи - PullRequest
0 голосов
/ 04 февраля 2020

Предположим, что у меня есть два интерфейса:

interface Box {
    x: number
    y: number
}

и

interface ColouredBox {
    x: number
    y: number
    colour: string
}

Предположим, что для целей этого вопроса я не могу изменить интерфейсы.

Теперь, когда я создаю объекты, у меня есть такой код:

let a: Box|ColouredBox = {x: 1, y: 2}
if( something ){
    a.colour = "Blue"  // Compilation Error
}

Я получаю эту ошибку на a.colour = "Blue":

Error:(24, 26) TS2339: Property 'colour' does not exist on type 'Box'.

Почему? Это ограничение компилятора TS? Кроме полной реконструкции объекта, есть ли другой рабочий процесс, который я мог бы использовать?

Ответы [ 2 ]

1 голос
/ 04 февраля 2020

Использование частичного

Вместо использования типа объединения можно попробовать использовать Частичное

let a: Partial<ColouredBox> = {x: 1, y: 2}

Частичное будет установлено все свойства ColoredBox необязательны.

Живой пример здесь .

Обновление :

Устраните интерфейс

Если вы хотите, чтобы цветовая часть интерфейса была необязательной, вы можете исключить один из интерфейсов.

interface Box {
  x: number;
  y: number;
  color?: string;
}

Затем, чтобы определить, работа с цветной рамкой:

if (box.color) { ... }

Тип Утверждение

Если вы придерживаетесь обоих интерфейсов, вы можете специально обработать a как ColouredBox, используя ключевое слово as (также известное как утверждение типа).

let a: Box | ColouredBox = { x: 1, y: 2 };
(a as ColouredBox).colour = "Blue";
1 голос
/ 04 февраля 2020

Вы можете использовать охрану типа in :

if ("colour" in a) {
    a.colour = "Blue"  // works
}

Это сузит до объединяемой части ColouredBox в зависимости от наличия свойства colour. В общем, вы можете выбрать только все общие свойства x / y из Box | ColouredBox, если они не были сужены ранее.

Пример реального кода здесь

...