Issue
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"
Solution
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"
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
Answered By - captain-yossarian
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.