@@ -640,14 +640,15 @@ namespace ts {
640640 const identityRelation = createMap<RelationComparisonResult>();
641641 const enumRelation = createMap<RelationComparisonResult>();
642642
643- type TypeSystemEntity = Symbol | Type | Signature;
643+ type TypeSystemEntity = Node | Symbol | Type | Signature;
644644
645645 const enum TypeSystemPropertyName {
646646 Type,
647647 ResolvedBaseConstructorType,
648648 DeclaredType,
649649 ResolvedReturnType,
650650 ImmediateBaseConstraint,
651+ EnumTagType,
651652 }
652653
653654 const enum CheckMode {
@@ -3470,8 +3471,8 @@ namespace ts {
34703471 const arity = getTypeReferenceArity(type);
34713472 const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
34723473 const hasRestElement = (<TupleType>type.target).hasRestElement;
3473- if (tupleConstituentNodes && tupleConstituentNodes.length > 0 ) {
3474- for (let i = (<TupleType>type.target).minLength; i < arity; i++) {
3474+ if (tupleConstituentNodes) {
3475+ for (let i = (<TupleType>type.target).minLength; i < Math.min( arity, tupleConstituentNodes.length) ; i++) {
34753476 tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ?
34763477 createRestTypeNode(createArrayTypeNode(tupleConstituentNodes[i])) :
34773478 createOptionalTypeNode(tupleConstituentNodes[i]);
@@ -4475,6 +4476,8 @@ namespace ts {
44754476 switch (propertyName) {
44764477 case TypeSystemPropertyName.Type:
44774478 return !!getSymbolLinks(<Symbol>target).type;
4479+ case TypeSystemPropertyName.EnumTagType:
4480+ return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType);
44784481 case TypeSystemPropertyName.DeclaredType:
44794482 return !!getSymbolLinks(<Symbol>target).declaredType;
44804483 case TypeSystemPropertyName.ResolvedBaseConstructorType:
@@ -8252,9 +8255,18 @@ namespace ts {
82528255 }
82538256
82548257 // JS are 'string' or 'number', not an enum type.
8255- const enumTag = symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
8258+ const enumTag = isInJSFile(node) && symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration);
82568259 if (enumTag) {
8257- return enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
8260+ const links = getNodeLinks(enumTag);
8261+ if (!pushTypeResolution(enumTag, TypeSystemPropertyName.EnumTagType)) {
8262+ return errorType;
8263+ }
8264+ let type = enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType;
8265+ if (!popTypeResolution()) {
8266+ type = errorType;
8267+ error(node, Diagnostics.Enum_type_0_circularly_references_itself, symbolToString(symbol));
8268+ }
8269+ return (links.resolvedEnumType = type);
82588270 }
82598271
82608272 // Get type from reference to named type that cannot be generic (enum or type parameter)
@@ -13373,7 +13385,7 @@ namespace ts {
1337313385 let propagationType: Type;
1337413386 inferFromTypes(originalSource, originalTarget);
1337513387
13376- function inferFromTypes(source: Type, target: Type) {
13388+ function inferFromTypes(source: Type, target: Type): void {
1337713389 if (!couldContainTypeVariables(target)) {
1337813390 return;
1337913391 }
@@ -13508,6 +13520,9 @@ namespace ts {
1350813520 inferFromTypes(getTrueTypeFromConditionalType(<ConditionalType>source), getTrueTypeFromConditionalType(<ConditionalType>target));
1350913521 inferFromTypes(getFalseTypeFromConditionalType(<ConditionalType>source), getFalseTypeFromConditionalType(<ConditionalType>target));
1351013522 }
13523+ else if (target.flags & TypeFlags.Conditional) {
13524+ inferFromTypes(source, getUnionType([getTrueTypeFromConditionalType(<ConditionalType>target), getFalseTypeFromConditionalType(<ConditionalType>target)]));
13525+ }
1351113526 else if (target.flags & TypeFlags.UnionOrIntersection) {
1351213527 const targetTypes = (<UnionOrIntersectionType>target).types;
1351313528 let typeVariableCount = 0;
@@ -13541,7 +13556,14 @@ namespace ts {
1354113556 }
1354213557 else {
1354313558 if (!(priority & InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) {
13544- source = getApparentType(source);
13559+ const apparentSource = getApparentType(source);
13560+ // getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
13561+ // If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes`
13562+ // with the simplified source.
13563+ if (apparentSource !== source && !(apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
13564+ return inferFromTypes(apparentSource, target);
13565+ }
13566+ source = apparentSource;
1354513567 }
1354613568 if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
1354713569 const key = source.id + "," + target.id;
@@ -13747,7 +13769,7 @@ namespace ts {
1374713769
1374813770 function hasPrimitiveConstraint(type: TypeParameter): boolean {
1374913771 const constraint = getConstraintOfTypeParameter(type);
13750- return !!constraint && maybeTypeOfKind(constraint, TypeFlags.Primitive | TypeFlags.Index);
13772+ return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint , TypeFlags.Primitive | TypeFlags.Index);
1375113773 }
1375213774
1375313775 function isObjectLiteralType(type: Type) {
@@ -14734,6 +14756,14 @@ namespace ts {
1473414756 // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
1473514757 // return the declared type.
1473614758 if (containsMatchingReference(reference, node)) {
14759+ // A matching dotted name might also be an expando property on a function *expression*,
14760+ // in which case we continue control flow analysis back to the function's declaration
14761+ if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
14762+ const init = getDeclaredExpandoInitializer(node);
14763+ if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
14764+ return getTypeAtFlowNode(flow.antecedent);
14765+ }
14766+ }
1473714767 return declaredType;
1473814768 }
1473914769 // Assignment doesn't affect reference
@@ -18208,7 +18238,7 @@ namespace ts {
1820818238 // Referencing abstract properties within their own constructors is not allowed
1820918239 if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
1821018240 const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
18211- if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node, declaringClassDeclaration )) {
18241+ if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
1821218242 error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); // TODO: GH#18217
1821318243 return false;
1821418244 }
@@ -18395,6 +18425,9 @@ namespace ts {
1839518425 }
1839618426 }
1839718427 }
18428+ else if (strictNullChecks && prop && prop.valueDeclaration && isPropertyAccessExpression(prop.valueDeclaration) && getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration)) {
18429+ assumeUninitialized = true;
18430+ }
1839818431 const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
1839918432 if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
1840018433 error(right, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
@@ -20192,18 +20225,15 @@ namespace ts {
2019220225 assigned || inferred;
2019320226 }
2019420227
20195- function getAssignedClassType(symbol: Symbol) {
20228+ function getAssignedClassType(symbol: Symbol): Type | undefined {
2019620229 const decl = symbol.valueDeclaration;
2019720230 const assignmentSymbol = decl && decl.parent &&
2019820231 (isFunctionDeclaration(decl) && getSymbolOfNode(decl) ||
2019920232 isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
2020020233 isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
20201- if (assignmentSymbol) {
20202- const prototype = forEach(assignmentSymbol.declarations, getAssignedJSPrototype);
20203- if (prototype) {
20204- return checkExpression(prototype);
20205- }
20206- }
20234+ const prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype" as __String);
20235+ const init = prototype && getAssignedJSPrototype(prototype.valueDeclaration);
20236+ return init ? checkExpression(init) : undefined;
2020720237 }
2020820238
2020920239 function getAssignedJSPrototype(node: Node) {
@@ -27419,12 +27449,12 @@ namespace ts {
2741927449 return result;
2742027450 }
2742127451
27422- function isNodeUsedDuringClassInitialization(node: Node, classDeclaration: ClassLikeDeclaration ) {
27452+ function isNodeUsedDuringClassInitialization(node: Node) {
2742327453 return !!findAncestor(node, element => {
27424- if (( isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) && element.parent === classDeclaration ) {
27454+ if (isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) {
2742527455 return true;
2742627456 }
27427- else if (element === classDeclaration || isFunctionLikeDeclaration(element)) {
27457+ else if (isClassLike( element) || isFunctionLikeDeclaration(element)) {
2742827458 return "quit";
2742927459 }
2743027460
0 commit comments