Imre_G
Imre_G

Reputation: 2535

How to make typescript take filtering on data type into account

I have these interfaces:

interface ParsedUrlQuery {
  [key: string]: string | string[]
}

interface URLParams {
  [key: string]: string
}

I then write the function:

const getParamsFromQuery = (query: ParsedUrlQuery): URLParams => {
  return Object.fromEntries(
    Object.entries(query).filter(([_key, value]) => typeof value === 'string')
  )
}

I get a typescript error:

Type '{ [k: string]: string | string[]; }' is not assignable to type 'URLParams'.
  'string' index signatures are incompatible.
    Type 'string | string[]' is not assignable to type 'string'.
      Type 'string[]' is not assignable to type 'string'.ts(2322)

Why does this not work and what do I need to make typescript take into account this filter action?

Upvotes: 0

Views: 495

Answers (1)

Marcus Dunn
Marcus Dunn

Reputation: 580

You are looking for a typeguard which lets you tell typescript that if your function returns true - then value is string.

const getParamsFromQuery = (query: ParsedUrlQuery): URLParams => {
  return Object.fromEntries(
    Object.entries(query).filter((kv): kv is [string, string] => typeof kv[1] === 'string')
  )
}

Upvotes: 2

Related Questions