Параметры обратного вызова Typescript зависят от параметров другого параметра

#typescript

#typescript

Вопрос:

У меня есть такие типы, как этот;

 type Admin = {
  propertyA: string;
  propertyB: string;
}

type User = {
  propertyC: string;
  propertyE: string;
}

interface AuthProviderProps {
  userType: 'user' | 'admin';
  onUserLoggedIn: (user) => void;
}
  

Как я могу передать правильный тип пользователя onUserLoggedIn зависит от userType

Ответ №1:

В качестве альтернативы общему решению от @AlexWayne вы можете использовать различаемое объединение.

Я предпочитаю это решение обобщенным, поскольку вам не нужно дважды повторять тип пользователя (один в общем параметре, второй в поле UserType)

 interface AuthProviderPropsUser {
  userType: 'user';
  onUserLoggedIn: (user: User) => void;
}

interface AuthProviderPropsAdmin {
  userType: 'admin';
  onUserLoggedIn: (user: Admin) => void;
}

type AuthProviderProps = AuthProviderPropsUser | AuthProviderPropsAdmin;

const x: AuthProviderProps = {
    userType: 'user',
    onUserLoggedIn: (user) => {
      console.log(user.propertyC); // OK
      console.log(user.propertyA); // Error Property 'propertyA' does not exist on type 'User'. Did you mean 'propertyC'?
    },
}
  

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

Ответ №2:

Здесь вам нужно использовать generics для захвата типа, а затем ссылаться на него в другом месте.

 interface AuthProviderProps<T extends 'user' | 'admin'> {
  userType: T;
  onUserLoggedIn: (user: T) => void;
}
  

Когда вы будете использовать вот так:

 const userProps: AuthProviderProps<'admin'> = {
  userType: 'admin',
  onUserLoggedIn(user) { // typescript knows user is of type 'admin' here
    console.log(user)
  }
}