Ключи условных объектов Typescript: свойство A существует Вероятность B должна существовать - PullRequest
0 голосов
/ 12 июля 2020

Фон

Я хочу условно ввести ключи в объекте на основе существования другого ключа в этом объекте.

Проблема

У меня есть объект, у которого есть требуемые ключи и некоторые дополнительные. Я не знаю, как сделать так, чтобы один из дополнительных ключей зависел от наличия другого дополнительного ключа. Например,

interface User { 
  username: string;
  id: string;
  member?: boolean; 
  memberStatus?: string;
}

Теперь предположим, что у меня есть список пользователей, которых я сопоставляю, и я хочу показать кнопку, если пользователь member, и сделать эту кнопку определенной c цвет основан на memberStatus.

return users.map(user => (
  if(user.member) { 
    //memberStatus here will cause an error because it maybe a string or undefined
    <button className={memberStatus === 'active' ? 'green' : 'yellow'}>Member Button</button>
  }
  return (
    <p>{user.username} is a user</p>
  )
))

Что я пробовал

Я искал расширения интерфейсов и условную типизацию. Тем не менее, расширение пользовательского интерфейса из пользовательского интерфейса оставляет мне дополнительные ключи.

Вопрос

Можно ли создать такой интерфейс

interface User { 
 username: string;
 id: string;
 member?: string;
 memberStatus: string; 
}

type UserOrMember = User.member ? User : Omit<User, 'memberStatus'>

apiUsers: UserOrMember = [...users]

Опять же, цель состоит в том, что memberStatus требуется только в том случае, если member не undefined.

Есть ли что-то, чего мне не хватает в расширяемых интерфейсах или универсальных шаблонах, которые могут быть полезны?

1 Ответ

2 голосов
/ 12 июля 2020

Вы можете попробовать Типы объединения с тегами :

// declare types
interface BaseUser {
  username: string;
  id: string;
  member?: boolean;
}

interface User extends BaseUser {
  member?: false;
}

interface Member extends BaseUser {
  member: true;
  memberStatus: string;
}

type UserOrMember = User | Member;

// usage in component
declare const user: UserOrMember
console.log(user.member ? user.memberStatus : user.username)

Ссылка на игровую площадку

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