Home > Enterprise >  Working with filtered types with using map / filter in Typescript
Working with filtered types with using map / filter in Typescript

Time:06-27

I realise this question is not specific to typescript, but leaving the below line (B) uncommented would give an error Property 'length' does not exist on type 'String | Number'. Is there some way to make it possible for typescript to know that all the elements are now only string (after the filtering is done)?

const array_: (String| Number)[] = [99, "Hello, World!"];

array_.map((e) => {if (typeof e === "string") console.log(e.length)}) // A

// array_.filter((e) => typeof e === "string").map((e) => {console.log(e.length)}) // B

https://onecompiler.com/typescript/3y88gzecj

CodePudding user response:

Sure, you need to use convert filter callback to typeguard:


const array_: (String | Number)[] = [99, "Hello, World!"];

array_.map((e) => { if (typeof e === "string") console.log(e.length) }) // A

array_.filter(
  (e): e is string => typeof e === "string").map((e) => {
    console.log(e.length)
  }) // ok

Callback (e): e is string => typeof e === "string"

Please see docs Playground

CodePudding user response:

Use Type predicates so TS knows what you're doing

const array_: (String| Number)[] = [99, "Hello, World!"];

const isString = (item: String | Number): item is String => typeof item === "string"

array_.map((e) => {if (typeof e === "string") console.log(e.length)})

array_.filter(isString).map((e) => {console.log(e.length)})
  • Related