Home > Software design >  How to extract keys of certain type from object
How to extract keys of certain type from object

Time:10-06

Lets say I have an interface Obj:

interface Obj {
  string1: string
  string2: string
  array1: SomeInterface[]
  array2: SomeOtherInterface[]
}

How can one extract the keys of the interface Obj that extends [] as a discriminated union type?

Desired output given Obj from above:

// "array1" | "array2"

CodePudding user response:

You need to use mapped types:

type SomeInterface = { tag: 'SomeInterface' }
type SomeOtherInterface = { tag: 'SomeOtherInterface' }

interface Obj {
    string1: string
    string2: string
    array1: SomeInterface[]
    array2: SomeOtherInterface[]
}

type ObtainKeys<Obj, Type> = {
    [Prop in keyof Obj]: Obj[Prop] extends Type ? Prop : never
}[keyof Obj]

type GetArrayKeys = ObtainKeys<Obj, Array<any>> // "array1" | "array2"

type GetStringKeys = ObtainKeys<Obj, string> //  "string1" | "string2"

Playground

ObtainKeys is a generic util, which expects two arguments. First one is an Object you want to check, second one is a type you want to extract.

This line: [Prop in keyof Obj]: Obj[Prop] extends Type ? Prop : never iterates over all Obj keys and checks whether Obj[Prop] extends desired type. Please keep in mind, that Obj[Prop] is a value and not a key. So, if Obj[Prop] meets the requirements - return Prop, otherwise - never.

I have used [keyof Obj] in order to get all values of our iterated type, because desired Prop is in the value place and union of any type with never - returns you same type without never

  • Related