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)})