Description
TypeScript Version: 3.3.0-dev.20181122
Search Terms: conditional type resolves any
Code
After adding exactly this many conditions, the type of WrappedJsxNodeType
will be any
.
import * as ts from "typescript";
type WrappedNodeType = CompilerNodeToWrappedType<ts.JsxExpression>;
type CompilerNodeToWrappedType<T extends ts.Node> = T extends ts.ArrayBindingPattern ? ArrayBindingPattern :
T extends ts.BindingElement ? BindingElement :
T extends ts.ObjectBindingPattern ? ObjectBindingPattern :
T extends ts.ClassDeclaration ? ClassDeclaration :
T extends ts.ClassExpression ? ClassExpression :
T extends ts.ConstructorDeclaration ? ConstructorDeclaration :
T extends ts.GetAccessorDeclaration ? GetAccessorDeclaration :
T extends ts.MethodDeclaration ? MethodDeclaration :
T extends ts.PropertyDeclaration ? PropertyDeclaration :
T extends ts.SetAccessorDeclaration ? SetAccessorDeclaration :
T extends ts.ComputedPropertyName ? ComputedPropertyName :
T extends ts.Identifier ? Identifier :
T extends ts.QualifiedName ? QualifiedName :
T extends ts.SyntaxList ? SyntaxList :
T extends ts.Decorator ? Decorator :
T extends ts.JSDoc ? JSDoc :
T extends ts.JSDocAugmentsTag ? JSDocAugmentsTag :
T extends ts.JSDocClassTag ? JSDocClassTag :
T extends ts.JSDocParameterTag ? JSDocParameterTag :
T extends ts.JSDocPropertyTag ? JSDocPropertyTag :
T extends ts.JSDocReturnTag ? JSDocReturnTag :
T extends ts.JSDocTypedefTag ? JSDocTypedefTag :
T extends ts.JSDocTypeTag ? JSDocTypeTag :
T extends ts.JSDocUnknownTag ? JSDocUnknownTag :
T extends ts.EnumDeclaration ? EnumDeclaration :
T extends ts.EnumMember ? EnumMember :
T extends ts.AsExpression ? AsExpression :
T extends ts.AwaitExpression ? AwaitExpression :
T extends ts.CallExpression ? CallExpression :
T extends ts.CommaListExpression ? CommaListExpression :
T extends ts.ConditionalExpression ? ConditionalExpression :
T extends ts.DeleteExpression ? DeleteExpression :
T extends ts.ImportExpression ? ImportExpression :
T extends ts.MetaProperty ? MetaProperty :
T extends ts.NewExpression ? NewExpression :
T extends ts.NonNullExpression ? NonNullExpression :
T extends ts.OmittedExpression ? OmittedExpression :
T extends ts.ParenthesizedExpression ? ParenthesizedExpression :
T extends ts.PartiallyEmittedExpression ? PartiallyEmittedExpression :
T extends ts.PostfixUnaryExpression ? PostfixUnaryExpression :
T extends ts.PrefixUnaryExpression ? PrefixUnaryExpression :
T extends ts.SpreadElement ? SpreadElement :
T extends ts.SuperElementAccessExpression ? SuperElementAccessExpression :
T extends ts.SuperExpression ? SuperExpression :
T extends ts.SuperPropertyAccessExpression ? SuperPropertyAccessExpression :
T extends ts.ThisExpression ? ThisExpression :
T extends ts.TypeAssertion ? TypeAssertion :
T extends ts.TypeOfExpression ? TypeOfExpression :
T extends ts.VoidExpression ? VoidExpression :
T extends ts.JsxExpression ? JsxExpression : Node<T>;
class Node<NodeType extends ts.Node = ts.Node> {
compilerNode!: NodeType;
}
class JsxExpression extends Node<ts.JsxExpression> {}
class ArrayBindingPattern extends Node<ts.ArrayBindingPattern> {}
class BindingElement extends Node<ts.BindingElement> {}
class ObjectBindingPattern extends Node<ts.ObjectBindingPattern> {}
class ClassDeclaration extends Node<ts.ClassDeclaration> {}
class ClassExpression extends Node<ts.ClassExpression> {}
class ConstructorDeclaration extends Node<ts.ConstructorDeclaration> {}
class GetAccessorDeclaration extends Node<ts.GetAccessorDeclaration> {}
class MethodDeclaration extends Node<ts.MethodDeclaration> {}
class PropertyDeclaration extends Node<ts.PropertyDeclaration> {}
class SetAccessorDeclaration extends Node<ts.SetAccessorDeclaration> {}
class ComputedPropertyName extends Node<ts.ComputedPropertyName> {}
class Identifier extends Node<ts.Identifier> {}
class QualifiedName extends Node<ts.QualifiedName> {}
class SyntaxList extends Node<ts.SyntaxList> {}
class Decorator extends Node<ts.Decorator> {}
class JSDoc extends Node<ts.JSDoc> {}
class JSDocAugmentsTag extends Node<ts.JSDocAugmentsTag> {}
class JSDocClassTag extends Node<ts.JSDocClassTag> {}
class JSDocParameterTag extends Node<ts.JSDocParameterTag> {}
class JSDocPropertyTag extends Node<ts.JSDocPropertyTag> {}
class JSDocReturnTag extends Node<ts.JSDocReturnTag> {}
class JSDocTypedefTag extends Node<ts.JSDocTypedefTag> {}
class JSDocTypeTag extends Node<ts.JSDocTypeTag> {}
class JSDocUnknownTag extends Node<ts.JSDocUnknownTag> {}
class EnumDeclaration extends Node<ts.EnumDeclaration> {}
class EnumMember extends Node<ts.EnumMember> {}
class AsExpression extends Node<ts.AsExpression> {}
class AwaitExpression extends Node<ts.AwaitExpression> {}
class CallExpression extends Node<ts.CallExpression> {}
class CommaListExpression extends Node<ts.CommaListExpression> {}
class ConditionalExpression extends Node<ts.ConditionalExpression> {}
class DeleteExpression extends Node<ts.DeleteExpression> {}
class ImportExpression extends Node<ts.ImportExpression> {}
class MetaProperty extends Node<ts.MetaProperty> {}
class NewExpression extends Node<ts.NewExpression> {}
class NonNullExpression extends Node<ts.NonNullExpression> {}
class OmittedExpression extends Node<ts.OmittedExpression> {}
class ParenthesizedExpression extends Node<ts.ParenthesizedExpression> {}
class PartiallyEmittedExpression extends Node<ts.PartiallyEmittedExpression> {}
class PostfixUnaryExpression extends Node<ts.PostfixUnaryExpression> {}
class PrefixUnaryExpression extends Node<ts.PrefixUnaryExpression> {}
class SpreadElement extends Node<ts.SpreadElement> {}
class SuperElementAccessExpression extends Node<ts.SuperElementAccessExpression> {}
class SuperExpression extends Node<ts.SuperExpression> {}
class SuperPropertyAccessExpression extends Node<ts.SuperPropertyAccessExpression> {}
class ThisExpression extends Node<ts.ThisExpression> {}
class TypeAssertion extends Node<ts.TypeAssertion> {}
class TypeOfExpression extends Node<ts.TypeOfExpression> {}
class VoidExpression extends Node<ts.VoidExpression> {}
If you remove the first condition in the type alias (T extends ts.ArrayBindingPattern ? ArrayBindingPattern :
) you will see it correctly resolve to JsxExpression
.
Expected behavior: Resolves to JsxExpression
Actual behavior: Resolves to any
.
I was code generating all this with ts-simple-ast until it failed (see here), so I tried randomly shuffling the array of type names I was generating it with to see if what was in the conditions mattered, but it always seemed to fail after 51 classes. (Edit: Updated example to step through the array of nodes and they all fail at 51 classes. Actually, in some cases when shuffling it would differ, but that was just because it happened to match a base type.)
My declaration files keep being generated with any
types and occasionally objects I use internally are typed as any
because of this issue. Perhaps there's a better way I can do this mapping? Thanks!