Home > front end >  TypeScript: get a property from conditional types
TypeScript: get a property from conditional types

Time:02-10

I'm trying to get a value that either can exist or not on the property. So I have 2 types: EmptyUser and UserResponse.

EmptyUser interface only has one property. UserResponse interface has a lot of properties AND id property that I need.

Then in my function I'm trying to use id, but I can't get it from the created types. Below is the example of code:

interface EmptyUser {
  // only this property
  unauthorized: boolean;
}

interface UserResponse {
  // ...a lot of different properties and
  id: number;
}

export type UsersType = EmptyUser | UserResponse;

interface State {
  users: UsersType,
}

then in my code I'm trying to get property id from state.users:

const { id }: UsersType = state.users;

and I receive an error: TS2339: Property 'id' does not exist on type 'UsersType'.

I would appreciate any help.

CodePudding user response:

With | you are saying that UsersType can be any one of EmptyUser or UserResponse. So id can not be guaranteed to be in UsersType.

If you do it individually, with either one of the types you will not have an issue. Link

interface EmptyUser {
  // only this property
  unauthorized: boolean;
}

interface UserResponse {
  // ...a lot of different properties and
  id: number;
}

export type UsersType = UserResponse;

interface State {
  users: UsersType,
}

let state : State = {
  users : {
    id : 2
  }
};

const { id }: UsersType = state.users;

But if you want an item to have properties from both, you need & intersection type.

interface EmptyUser {
  // only this property
  unauthorized: boolean;
}

interface UserResponse {
  // ...a lot of different properties and
  id: number;
}

export type UsersType = EmptyUser & UserResponse;

interface State {
  users: UsersType,
}

let state : State = {
  users : {
    id : 2,
    unauthorized : false
  }
};

const { id }: UsersType = state.users;

Playground Link

CodePudding user response:

Please try below code.

interface EmptyUser {
   // only this property
   unauthorized: boolean;
}

interface UserResponse {
   // ...a lot of different properties and
   id: number;
}

type UsersType = EmptyUser | UserResponse;

 interface State {
   users: UsersType,
 }

 let state : State = {
   users : {
      id : 2,
      unauthorized : false
   }
 };

const { id }  = state.users as UserResponse;
console.log(id);

Playground link

  • Related