Как объявить переменную типа A или B, когда одна расширяет другую в Typescript

0

Вопрос

У меня есть поставщик контекста, который передает пользовательские данные по всему приложению.

У меня есть студенческий интерфейс:

export interface Student extends User

Я хотел бы, чтобы поставщик возвращал пользовательские данные типа Student или User следующим образом:

let userData: Student | User = null;

При попытке получить доступ к свойству, доступному только студентам, userData?.currentTeam, VS Код выдает следующую ошибку:

Property 'currentTeam' does not exist on type 'Student | User'.
  Property 'currentTeam' does not exist on type 'User'.ts(2339)

Мне нужна помощь, чтобы выяснить, почему по умолчанию используется родительский интерфейс и как разрешить оба варианта.

1

Лучший ответ

1

Это стандартное поведение союзов: если вы не сделаете что-то, чтобы проверить, с каким типом вы имеете дело, typescript позволит вам получить доступ только к свойствам, существующим у всех членов союза.

Вот несколько примеров того, как вы можете сузить тип. Вы можете проверить, существует ли это свойство:

if ('currentTeam' in userData) {
  console.log(userData.currentTeam);
}

Или, если вы создали классы (которых у вас может и не быть), вы можете использовать экземпляр:

if (userData instanceof Student) {
  console.log(userData.currentTeam);
}

Или вы можете изменить типы, чтобы у всех них было общее свойство, которое вы затем можете проверить, с каким типом вы имеете дело. Это иногда называют "дискриминационным союзом".

interface User {
  type: 'user',
  // rest of the type here
}

interface Student extends User {
  type: 'student',
  currentTeam: // something,
  // rest of the type here
}

if (userData.type === 'student') {
  console.log(userData.currentTeam);
}
2021-11-24 00:11:30

Спасибо. Я смог использовать это, чтобы установить значение по умолчанию в поле формы с помощью троичного: 'currentTeam' in userData ? userData.currentTeam.teamName: 'No Team Set'
Rafael Zasas

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................