skip to Main Content

Long story short, I’m performing an API call, and this is the data that I’m getting back:

{
  getUserInfo: {
    country: 'DE',
    email: '[email protected]',
    id: '123456',
    name: 'Test Person'
  }
}

I have defined a type to match that response:

type UserInfoResponse = {
  getUserInfo: {
    country: string,
    name: string|undefined,
    email: string,
    id: string,
  } 
}

Once I’ve done the call, I don’t need that outer layer with the getUserInfo key anymore, so I’ve defined another type:

type PlayerInfo = {
  country: string,
  name: string|undefined,
  email: string,
  id: string,
}

I would like to cast the content of the UserInfoResponse to PlayerInfo:

async getUserInfo(): Promise<PlayerInfo> {
  // here all the code that initializes the API client and performs the call
  const data = {
    getUserInfo: {
      country: 'DE',
      email: '[email protected]',
      id: '123456',
      name: 'Test Person'
    }
  }

  return data.getUserInfo as PlayerInfo // this does not work
}

This is the error I get:

Conversion of type 'UserInfoResponse' to type 'PlayerInfo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'UserInfoResponse' is missing the following properties from type 'PlayerInfo': country, name, email, id

But why? data.getUserInfo contains exactly the fields that PlayerInfo needs, and data.getUserInfo isnt’t of the UserInfoResponse type, data is.
return data.getUserInfo as PlayerInfo works, but why do I have to pass through undefined at all?

I also tried changing the type to

{
  getUserInfo: PlayerInfo
}

but this didn’t help either.

2

Answers


  1. You don’t need 2 types that are the same though. You can use your other type inside the other object type

    type PlayerInfo = {
      country: string,
      name: string|undefined,
      email: string,
      id: string,
    }
    
    type UserInfoResponse = {
      getUserInfo: PlayerInfo 
    }
    

    Aside from that your error Type 'UserInfoResponse' is missing the following properties implies that your assigning the other base type to this base type which doesn’t work because they are not the same type. One has the same type nested in the other. So this means your error is in your get UserInfoResponse function.

    async getUserInfo(): Promise<PlayerInfo> {
      const data = {
        getUserInfo: {
          country: 'DE',
          email: '[email protected]',
          id: '123456',
          name: 'Test Person'
        }
    
       return Promise.resolve(data.getUserInfo);
    }
    

    your const data was a type of UserInfoResponse, you need to return the member of that object which is getUserInfo which is the correct type of PlayerInfo. You also have a promise as a return type and are not returning a promise but the playerInfo object.

    Here is a full working example of what you want in TS playground.

    Working Example

    Login or Signup to reply.
  2. You can use an "adapter" function

    const userInfoAdapter = (getUserInfo) => {
        const { country, email, id, name } = getUserInfo;
    
        return {
            country, email, id, name
        } as PlayerInfo;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search