Argument of type 'string | number' is not assignable to parameter of type 'number'

Veryon890 picture Veryon890 · Mar 6, 2020 · Viewed 7.1k times · Source

Question Modified With an example method to the end: -

I have an interface as shown below for typing an object.

export interface IList{
  name: string;
  age: number;
  option: number;
  quantity: number;
  priority: number;
}

Due to some requirement I have to assign a "string" to the "priority" property at the end of all operations before sending it to the backend.

As I've to assign a string, I tried using a union operator :-

priority : number | string; But all the other pieces of code wherever I used other operations taking this as a number into consideration is also throwing me the below error:

Argument of type 'string | number' is not assignable to parameter of type 'number'
  Type 'string' is not assignable to type 'number'.

How do I get around this and use priority as a both a string and number to type my object.

Here is one condition where I am using the "IList" interface as a type and assigning a number if multiGroupHeader is true, else I have to assign a string :-

public updatePriorities(Lists: IList[]) {
  if (!this.multiGroupHeader) {
    const priorities = Lists.map((list: IList) => list.priority);
    const uniquePriorities = [...new Set(priorities)];
    if (uniquePriorities.length === 1 && uniquePriorities[0] === 1) {
      return;
    }
    uniquePriorities.sort((priority1: number, priority2: number) => priority1 - priority2);
    const updatedPriorities = uniquePriorities.map((priority: number, index: number) => {
      return index + 1;
    });

    uniquePriorities.forEach((id: number, index: number) => {
      Lists.forEach((list: IList) => {
        if (list.priority === id) {
          list.priority = updatedPriorities[index];
        }
      });
    });
  } else {
    Lists.forEach((list: IList) => (list.priority = "CURRENT"));
  }
}

Answer

night_owl picture night_owl · Mar 6, 2020

One way you can work around this is by asserting/narrowing the type before handing it to the functions that expect only a string or number:

if (typeof list.priority === 'number') {
  // list.priority's type inside these braces is only 'number'
}

There are other ways assert the type of a variable, too: https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions