@@ -42,10 +42,10 @@ namespace ts {
4242 iterableCacheKey: "iterationTypesOfAsyncIterable" | "iterationTypesOfIterable";
4343 iteratorCacheKey: "iterationTypesOfAsyncIterator" | "iterationTypesOfIterator";
4444 iteratorSymbolName: "asyncIterator" | "iterator";
45- getGlobalIteratorType: (reportErrors: boolean) => Type ;
46- getGlobalIterableType: (reportErrors: boolean) => Type ;
47- getGlobalIterableIteratorType: (reportErrors: boolean) => Type ;
48- getGlobalGeneratorType: (reportErrors: boolean) => Type ;
45+ getGlobalIteratorType: (reportErrors: boolean) => GenericType ;
46+ getGlobalIterableType: (reportErrors: boolean) => GenericType ;
47+ getGlobalIterableIteratorType: (reportErrors: boolean) => GenericType ;
48+ getGlobalGeneratorType: (reportErrors: boolean) => GenericType ;
4949 resolveIterationType: (type: Type, errorNode: Node | undefined) => Type | undefined;
5050 mustHaveANextMethodDiagnostic: DiagnosticMessage;
5151 mustBeAMethodDiagnostic: DiagnosticMessage;
@@ -9531,24 +9531,10 @@ namespace ts {
95319531 return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
95329532 }
95339533
9534- function createAsyncGeneratorType(yieldType: Type, returnType: Type, nextType: Type) {
9535- const globalAsyncGeneratorType = getGlobalAsyncGeneratorType(/*reportErrors*/ true);
9536- if (globalAsyncGeneratorType !== emptyGenericType) {
9537- yieldType = getAwaitedType(yieldType) || unknownType;
9538- returnType = getAwaitedType(returnType) || unknownType;
9539- nextType = getAwaitedType(nextType) || unknownType;
9540- }
9541- return createTypeFromGenericGlobalType(globalAsyncGeneratorType, [yieldType, returnType, nextType]);
9542- }
9543-
95449534 function createIterableType(iteratedType: Type): Type {
95459535 return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
95469536 }
95479537
9548- function createGeneratorType(yieldType: Type, returnType: Type, nextType: Type) {
9549- return createTypeFromGenericGlobalType(getGlobalGeneratorType(/*reportErrors*/ true), [yieldType, returnType, nextType]);
9550- }
9551-
95529538 function createArrayType(elementType: Type, readonly?: boolean): ObjectType {
95539539 return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
95549540 }
@@ -9904,28 +9890,28 @@ namespace ts {
99049890 return links.resolvedType;
99059891 }
99069892
9907- function addTypeToIntersection(typeSet: Type[] , includes: TypeFlags, type: Type) {
9893+ function addTypeToIntersection(typeSet: Map< Type> , includes: TypeFlags, type: Type) {
99089894 const flags = type.flags;
99099895 if (flags & TypeFlags.Intersection) {
99109896 return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
99119897 }
99129898 if (isEmptyAnonymousObjectType(type)) {
99139899 if (!(includes & TypeFlags.IncludesEmptyObject)) {
99149900 includes |= TypeFlags.IncludesEmptyObject;
9915- typeSet.push( type);
9901+ typeSet.set(type.id.toString(), type);
99169902 }
99179903 }
99189904 else {
99199905 if (flags & TypeFlags.AnyOrUnknown) {
99209906 if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
99219907 }
9922- else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains( typeSet, type)) {
9908+ else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !typeSet.has( type.id.toString() )) {
99239909 if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) {
99249910 // We have seen two distinct unit types which means we should reduce to an
99259911 // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
99269912 includes |= TypeFlags.NonPrimitive;
99279913 }
9928- typeSet.push( type);
9914+ typeSet.set(type.id.toString(), type);
99299915 }
99309916 includes |= flags & TypeFlags.IncludesMask;
99319917 }
@@ -9934,7 +9920,7 @@ namespace ts {
99349920
99359921 // Add the given types to the given type set. Order is preserved, freshness is removed from literal
99369922 // types, duplicates are removed, and nested types of the given kind are flattened into the set.
9937- function addTypesToIntersection(typeSet: Type[] , includes: TypeFlags, types: ReadonlyArray<Type>) {
9923+ function addTypesToIntersection(typeSet: Map< Type> , includes: TypeFlags, types: ReadonlyArray<Type>) {
99389924 for (const type of types) {
99399925 includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
99409926 }
@@ -10041,8 +10027,9 @@ namespace ts {
1004110027 // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
1004210028 // for intersections of types with signatures can be deterministic.
1004310029 function getIntersectionType(types: ReadonlyArray<Type>, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
10044- const typeSet: Type[] = [];
10045- const includes = addTypesToIntersection(typeSet, 0, types);
10030+ const typeMembershipMap: Map<Type> = createMap();
10031+ const includes = addTypesToIntersection(typeMembershipMap, 0, types);
10032+ const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
1004610033 // An intersection type is considered empty if it contains
1004710034 // the type never, or
1004810035 // more than one unit type or,
@@ -20583,10 +20570,15 @@ namespace ts {
2058320570 }
2058420571 propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
2058520572 }
20573+ return getFlowTypeOfAccessExpression(node, prop, propType, right);
20574+ }
20575+
20576+ function getFlowTypeOfAccessExpression(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, propType: Type, errorNode: Node) {
2058620577 // Only compute control flow type if this is a property access expression that isn't an
2058720578 // assignment target, and the referenced property was declared as a variable, property,
2058820579 // accessor, or optional method.
20589- if (node.kind !== SyntaxKind.PropertyAccessExpression ||
20580+ const assignmentKind = getAssignmentTargetKind(node);
20581+ if (node.kind !== SyntaxKind.ElementAccessExpression && node.kind !== SyntaxKind.PropertyAccessExpression ||
2059020582 assignmentKind === AssignmentKind.Definite ||
2059120583 prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) {
2059220584 return propType;
@@ -20596,7 +20588,7 @@ namespace ts {
2059620588 // and if we are in a constructor of the same class as the property declaration, assume that
2059720589 // the property is uninitialized at the top of the control flow.
2059820590 let assumeUninitialized = false;
20599- if (strictNullChecks && strictPropertyInitialization && left .kind === SyntaxKind.ThisKeyword) {
20591+ if (strictNullChecks && strictPropertyInitialization && node.expression .kind === SyntaxKind.ThisKeyword) {
2060020592 const declaration = prop && prop.valueDeclaration;
2060120593 if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
2060220594 const flowContainer = getControlFlowContainer(node);
@@ -20613,7 +20605,7 @@ namespace ts {
2061320605 }
2061420606 const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
2061520607 if (assumeUninitialized && !(getFalsyFlags(propType) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
20616- error(right , Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
20608+ error(errorNode , Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217
2061720609 // Return the declared type to reduce follow-on errors
2061820610 return propType;
2061920611 }
@@ -20970,7 +20962,7 @@ namespace ts {
2097020962 AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) :
2097120963 AccessFlags.None;
2097220964 const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
20973- return checkIndexedAccessIndexType(indexedAccessType, node);
20965+ return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression) , node);
2097420966 }
2097520967
2097620968 function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
@@ -23397,9 +23389,36 @@ namespace ts {
2339723389 }
2339823390
2339923391 function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
23400- return isAsyncGenerator
23401- ? createAsyncGeneratorType(yieldType, returnType, nextType)
23402- : createGeneratorType(yieldType, returnType, nextType);
23392+ const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
23393+ const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
23394+ yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
23395+ returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType;
23396+ nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType;
23397+ if (globalGeneratorType === emptyGenericType) {
23398+ // Fall back to the global IterableIterator if returnType is assignable to the expected return iteration
23399+ // type of IterableIterator, and the expected next iteration type of IterableIterator is assignable to
23400+ // nextType.
23401+ const globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
23402+ const iterationTypes = globalType !== emptyGenericType ? getIterationTypesOfGlobalIterableType(globalType, resolver) : undefined;
23403+ const iterableIteratorReturnType = iterationTypes ? iterationTypes.returnType : anyType;
23404+ const iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : undefinedType;
23405+ if (isTypeAssignableTo(returnType, iterableIteratorReturnType) &&
23406+ isTypeAssignableTo(iterableIteratorNextType, nextType)) {
23407+ if (globalType !== emptyGenericType) {
23408+ return createTypeFromGenericGlobalType(globalType, [yieldType]);
23409+ }
23410+
23411+ // The global IterableIterator type doesn't exist, so report an error
23412+ resolver.getGlobalIterableIteratorType(/*reportErrors*/ true);
23413+ return emptyObjectType;
23414+ }
23415+
23416+ // The global Generator type doesn't exist, so report an error
23417+ resolver.getGlobalGeneratorType(/*reportErrors*/ true);
23418+ return emptyObjectType;
23419+ }
23420+
23421+ return createTypeFromGenericGlobalType(globalGeneratorType, [yieldType, returnType, nextType]);
2340323422 }
2340423423
2340523424 function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode | undefined) {
@@ -24719,6 +24738,12 @@ namespace ts {
2471924738 || anyType;
2472024739 }
2472124740
24741+ const contextualReturnType = getContextualReturnType(func);
24742+ if (contextualReturnType) {
24743+ return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, contextualReturnType, isAsync)
24744+ || anyType;
24745+ }
24746+
2472224747 return anyType;
2472324748 }
2472424749
@@ -28240,6 +28265,13 @@ namespace ts {
2824028265 return (type as IterableOrIteratorType)[resolver.iterableCacheKey];
2824128266 }
2824228267
28268+ function getIterationTypesOfGlobalIterableType(globalType: Type, resolver: IterationTypesResolver) {
28269+ const globalIterationTypes =
28270+ getIterationTypesOfIterableCached(globalType, resolver) ||
28271+ getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
28272+ return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
28273+ }
28274+
2824328275 /**
2824428276 * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
2824528277 * type from from common heuristics.
@@ -28265,10 +28297,7 @@ namespace ts {
2826528297 // iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins.
2826628298 // While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
2826728299 // different definitions.
28268- const globalIterationTypes =
28269- getIterationTypesOfIterableCached(globalType, resolver) ||
28270- getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
28271- const { returnType, nextType } = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
28300+ const { returnType, nextType } = getIterationTypesOfGlobalIterableType(globalType, resolver);
2827228301 return (type as IterableOrIteratorType)[resolver.iterableCacheKey] = createIterationTypes(yieldType, returnType, nextType);
2827328302 }
2827428303
0 commit comments