Могу ли я сделать тип свойства объекта зависимым от другого типа свойства? - PullRequest
0 голосов
/ 29 апреля 2019

У меня есть объект, который выглядит так:

interface AuthState {
  isSignedIn: boolean
  token?: string
  user?: User
}

user может быть неопределенным, но только если isSignedIn === false. В приложении невозможно иметь isSignedIn === true и никакой пользовательский объект. Я хотел бы иметь возможность обеспечить это и избежать необходимости делать следующее:

// If I don't check for `user`, TS will throw an error since it doesn't see any
// relation between the 2 properties
const userName = isSignedIn && user && user.name

1 Ответ

0 голосов
/ 29 апреля 2019

Если я понимаю ваш вопрос, это должно быть то, что вы ищете.

interface FalseAuthState {
  isSignedIn: false;
}

interface TrueAuthState {
  isSignedIn: true;
  token: string;
  user: User;
}

type AuthState = FalseAuthState | TrueAuthState;

Итак, если бы у вас был объект типа

// This does not throw an error because Typescript knows it's correct
const noAuth: AuthState = {
   isAuth: false
} 

// This will throw an error because Typescript demands a User and Token.
const yesAuth: AuthState = {
   isAuth: true
} 

// This will not throw an error.
const realAuth: AuthState = {
  isAuth: true,
  token: "ABCD123",
  user: new User()
} 

function printUser(auth: AuthState) {
  if (auth.isAuth) {
     console.log(auth.user); // Typescript knows there's supposed to be a user so there is no error
  }
}

function badPrintUser(auth: AuthState) {
   if (auth.isAuth === false) {
      console.log(auth.user); // Typescript will throw an error because there's no supposed to be a user here.
   }
}

в вашемНапример, способ проверки такой:

const userName = auth.isSignedIn && auth.user.name

или

const userName = auth.isSignedIn ? auth.user.name : undefined;

К сожалению, вы не сможете удалить атрибуты из самого объекта и использовать этов ваших интересах.Если бы вы сделали это

const { isSignedIn, user } = (auth as TrueAuthState);
const userName = isSignedIn && user && user.name; // You still have to do this unless you really sure that the auth is a TrueAuthState
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...