Right now the CompilerNodeToWrappedType type will sometimes resolve to any:
The reason for this is a limitation in the typescript compiler where you cannot nest more than 50 conditional types: https://github.com/Microsoft/TypeScript/issues/28663
I spent a decent amount of time yesterday trying to come up with some workarounds, but unfortunately it seems like doing a long conditional type like this is the only thing that will work.
Since compiler nodes have the kind property set to enable differentiated union behavior, could you do something like this?
export enum SyntaxKind {
ArrayBindingPattern,
ObjectBindingPattern,
SomeUnknownKind
}
interface Node {
kind: SyntaxKind
}
interface WrappedNode {
z: number
}
interface ArrayNode {
kind: SyntaxKind.ArrayBindingPattern
a: string
}
interface WrappedArrayNode { a: number, itemType: string }
interface ObjectNode {
kind: SyntaxKind.ObjectBindingPattern
b: string
}
interface WrappedObjectNode { b: string, itemType: string }
interface CompilerToWrappedMap {
[SyntaxKind.ArrayBindingPattern]: WrappedArrayNode;
[SyntaxKind.ObjectBindingPattern]: WrappedObjectNode
}
type CompilerNodeToWrappedType<T extends Node> =
T['kind'] extends keyof CompilerToWrappedMap ?
CompilerToWrappedMap[T['kind']] :
WrappedNode
type Arr = CompilerNodeToWrappedType<ArrayNode> // => WrappedArrayNode
@Gerrit0 you just made my day!!! 馃槃
I had tried that in the past, but ran into issues I didn't understand... so I didn't consider it again. I ran into issues this time too, but now I had my npm run code-verification validate-compiler-node-to-wrapped-type script to run each time to validate all the possible passed in types. With the help of that, I was able to come up with the following type that falls below the max depth of 50.
export type CompilerNodeToWrappedType<T extends ts.Node> =
T extends ts.ObjectDestructuringAssignment ? compiler.ObjectDestructuringAssignment :
T extends ts.ArrayDestructuringAssignment ? compiler.ArrayDestructuringAssignment :
T extends ts.SuperElementAccessExpression ? compiler.SuperElementAccessExpression :
T extends ts.SuperPropertyAccessExpression ? compiler.SuperPropertyAccessExpression :
T extends ts.AssignmentExpression<infer U> ? compiler.AssignmentExpression<ts.AssignmentExpression<U>, U> :
T['kind'] extends keyof ImplementedKindToNodeMappings ? ImplementedKindToNodeMappings[T['kind']] :
T extends ts.SyntaxList ? compiler.SyntaxList :
T extends ts.TypeNode ? compiler.TypeNode :
T extends ts.TypeElement ? compiler.TypeElement :
T extends ts.JSDocTag ? compiler.JSDocTag :
T extends ts.LiteralExpression ? compiler.LiteralExpression :
T extends ts.PrimaryExpression ? compiler.PrimaryExpression :
T extends ts.MemberExpression ? compiler.MemberExpression :
T extends ts.LeftHandSideExpression ? compiler.LeftHandSideExpression :
T extends ts.UpdateExpression ? compiler.UpdateExpression :
T extends ts.UnaryExpression ? compiler.UnaryExpression :
T extends ts.Expression ? compiler.Expression :
T extends ts.IterationStatement ? compiler.IterationStatement :
T extends ts.Statement ? compiler.Statement :
compiler.Node<T>;
I'll do a release sometime today or tomorrow with this fix (need to run some errands and then clean up some scripts a bit).
Awesome!
This is released in 19.1.0. Thanks again @Gerrit0!