Issue
I would like to filter a specific generic type according to a static property. It's easier to show than to explain. I am happy to rephrase the question if anyone can give me a hint how to describe it better (things are quite abstract for a TS novice like me).
// My given types
interface ChardataNode {
type: "Chardata"
value: string
}
interface ElementNode<TName extends string = string, TChild extends Child = Child> {
type: "Element"
name: TName
children: TChild[]
}
type Child = ElementNode | ChardataNode
// This is what I tried. Unfortunately, the first utility type does not work at all as it doesn't filter out the element children
type ElementChildren<TParent> = TParent extends ElementNode ? TParent["children"][0]["type"] extends "Element" ? TParent["children"] : never : never
type ElementNames<TElements> = TElements extends ElementNode[] ? TElements[0]["name"] : never
// Setup an example type for testing
type X = ElementNode<"Root", ChardataNode | ElementNode<"Child1", never> | ElementNode<"Child2", never>>
// What I want is: "Child1" | "Child2", but what I get is: never
type Names = ElementNames<ElementChildren<X>>
Solution
In the end, I came up with this solution:
// My given types
interface ChardataNode {
type: "Chardata"
value: string
}
interface ElementNode<TName extends string = string, TChild extends Child = Child> {
type: "Element"
name: TName
children: TChild[]
}
type Child = ElementNode | ChardataNode
// The fixed utility types
type ElementChildren<TParent> = TParent extends ElementNode ? Extract<TParent["children"][0], ElementNode> : never
type ElementNames<TElement> = TElement extends ElementNode ? TElement["name"] : never
// Setup an example type for testing
type X = ElementNode<"Root", ChardataNode | ElementNode<"Child1", never> | ElementNode<"Child2", never>>
// Results in "Child1" | "Child2"
type Names = ElementNames<ElementChildren<X>>
Answered By - medihack
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.