liftingturn
liftingturn

Reputation: 83

How can i use Array.includes in typescript between different types

if Array.includes() result type is more tight type of input object type, it makes error. how can i handle this? this is the example of case.

index.d.ts

type OddNumberType = 1|3|5|7|9
type AllNumberType = OddNumberType|0|1|...|9

businessLogic.ts

let targetNumber:AllNumberType = parseInt(Math.random*10)
const oddArray:OddNumberType[] = [1,3,5,7,9]
let resultNumber:OddNumberType = 1;

if(oddArray.includes(targetNumber)){
 resultNumber = targetNumber
}

ts problem

Type 'AllNumberType' is not assignable to type 'OddNumberType'.
  Type 2 is not assignable to type 'OddNumberType'.ts(2322)

Upvotes: 6

Views: 3080

Answers (3)

Sodj
Sodj

Reputation: 959

The quick fix would be to add as:

const myArray: string[] = ["1", "2", "3"]
const value: number|string = ["1", 2, 3].random() 

myArray.includes(value as string)

It would be better if the param of includes accepts any type that includes the array's type.

Upvotes: 0

liftingturn
liftingturn

Reputation: 83

  for (const oddNum of oddArray) {
    if (oddNum === targetNumber) {
      resultNumber = oddNum;
      break;
    }
  }

for loop was answer. array.find or array.includes can not use between different in&out type?

Upvotes: 0

kaya3
kaya3

Reputation: 51043

It seems you want to use oddArray.includes as if it is a type guard which accepts an arbitrary number as its argument, and if it returns true, then Typescript should narrow the argument's type to be OddNumberType.

The Array.includes method is not declared as a type guard like this, and should not be: if a type guard returns false that should mean the argument is not of the type it guards, but generally if an array of some type T[] does not include an element, that does not mean the element is not of type T. There is something special about your array which makes its includes method a sensible type guard in this specific case - it is not just an array of OddNumberType values, it is an array of every OddNumberType value.

So, we can declare a type ArrayOfEveryOddNumber which is the same as OddNumberType[] but its includes method is a type guard:

type ArrayOfEveryOddNumber = OddNumberType[] & {
    includes(arg: AllNumberType): arg is OddNumberType
}
const oddArray = [1, 3, 5, 7, 9] as ArrayOfEveryOddNumber;

Note that a type assertion as ArrayOfEveryOddNumber is also needed.

Playground Link

Upvotes: 8

Related Questions