How to write a conditional promise.resolve properly in typescript?

Viewed 99

I have a project in react native using typescript and I would like to use Promise.resolve().then() of an object with a condition which causing a type error in typescript. Below is the situation:

I have the first object (as sample):

const objectA = async () => {
  // get the object from local storage
  const user = await asyncStorage.getItem(userAKey)

  return {
    // types are all in string
    id: user?.id || '',
    email: user?.email || '',
  }
}

And I have my second object (as sample):

const objectB = async () => {
  // get the object from local storage
  const user = await asyncStorage.getItem(userBKey)

  return {
    // types are all in string
    id: user?.id || '',
    email: user?.email || '',
    organisation: user?.organisation || ''
  }
}

So both objects have different types and keys with value. Here is the problem, I have a condition to check which object to be resolve based on some host type:

const objectTobeResolved = type === 'primary' ? objectA : objectB

So based on that condition, I pass it to the Promise:

const userData = () => {
   Promise.resolve(objectTobeResolved).then((values) => { ... })
}

I will get the type error here in the typescript for objectTobeResolved. Basically the type error here is mentioning something like objectA | objectB, but I actually only need to pass one of the object based on the condition above and I don't need the objectA | objectB condition as it is only either objectA or objectB based on the declared host type I had in the app launcher.

I don't quite understand how to declare it properly in typescript since I have just learned to use Typescript.

What is a right way to write the promise here? should I use race or all instead? But I only need to check one object at a time. Or should I declare or initialise in a certain way? Or maybe I don't even need to use promise at all?

Edit: I have updated the codes above to my real case scenario. The codes are actually running correctly, just that the type error keep showing up and I couldn't pass the test. A shortcut is to use //@ts-ignore, but since our practice is to not ignore the warning, so I'm trying to find a correct way to write it without having a warning which causing the test to be failed.

1 Answers

More code would be helpful, but I think what you may be asking about is how to create a union type so you can effectively refer to your result being a this or that. If so, maybe you could use something like this? I believe you could state it a number of other ways too, but I just wanted to illustrate the point.

const objectA = {
    a: 1,
    b: 2,
}

const objectB = {
    c: 3,
    d: 4,
    e: 5,
}

interface ABtype {
    a: Number
    b: Number
}

interface CDEtype {
    c: Number
    d: Number
    e: Number
}

interface ABpromiseType extends Promise<ABtype> {
}

interface CDEpromiseType extends Promise<CDEtype> {
}

interface ABCDEunionTypeCombined extends Promise<CDEtype | ABtype> {
}

// Something randomly true or false.
let conditionalCheck = new Date().getTime() % 2 == 0;

const someFunction = () => {
    const objectTobeResolved : ABCDEunionTypeCombined  = (conditionalCheck ? Promise.resolve(objectA) : Promise.resolve(objectB) );
}
Related