@@ -171,6 +171,7 @@ import {
171171 EnumMember,
172172 EnumType,
173173 equateValues,
174+ ErrorOutputContainer,
174175 escapeLeadingUnderscores,
175176 escapeString,
176177 EvaluatorResult,
@@ -20608,7 +20609,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2060820609 expr: Expression | undefined,
2060920610 headMessage: DiagnosticMessage | undefined,
2061020611 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20611- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20612+ errorOutputContainer: ErrorOutputContainer | undefined,
2061220613 ): boolean {
2061320614 if (isTypeRelatedTo(source, target, relation)) return true;
2061420615 if (!errorNode || !elaborateError(expr, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) {
@@ -20628,7 +20629,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2062820629 relation: Map<string, RelationComparisonResult>,
2062920630 headMessage: DiagnosticMessage | undefined,
2063020631 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20631- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20632+ errorOutputContainer: ErrorOutputContainer | undefined,
2063220633 ): boolean {
2063320634 if (!node || isOrHasGenericConditional(target)) return false;
2063420635 if (
@@ -20672,7 +20673,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2067220673 relation: Map<string, RelationComparisonResult>,
2067320674 headMessage: DiagnosticMessage | undefined,
2067420675 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20675- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20676+ errorOutputContainer: ErrorOutputContainer | undefined,
2067620677 ): boolean {
2067720678 const callSignatures = getSignaturesOfType(source, SignatureKind.Call);
2067820679 const constructSignatures = getSignaturesOfType(source, SignatureKind.Construct);
@@ -20705,7 +20706,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2070520706 target: Type,
2070620707 relation: Map<string, RelationComparisonResult>,
2070720708 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20708- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20709+ errorOutputContainer: ErrorOutputContainer | undefined,
2070920710 ): boolean {
2071020711 // Don't elaborate blocks
2071120712 if (isBlock(node.body)) {
@@ -20796,7 +20797,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2079620797 target: Type,
2079720798 relation: Map<string, RelationComparisonResult>,
2079820799 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20799- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20800+ errorOutputContainer: ErrorOutputContainer | undefined,
2080020801 ) {
2080120802 // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span
2080220803 let reportedError = false;
@@ -20876,7 +20877,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2087620877 target: Type,
2087720878 relation: Map<string, RelationComparisonResult>,
2087820879 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20879- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20880+ errorOutputContainer: ErrorOutputContainer | undefined,
2088020881 ) {
2088120882 const tupleOrArrayLikeTargetParts = filterType(target, isArrayOrTupleLikeType);
2088220883 const nonTupleOrArrayLikeTargetParts = filterType(target, t => !isArrayOrTupleLikeType(t));
@@ -20978,7 +20979,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2097820979 target: Type,
2097920980 relation: Map<string, RelationComparisonResult>,
2098020981 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
20981- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
20982+ errorOutputContainer: ErrorOutputContainer | undefined,
2098220983 ) {
2098320984 let result = elaborateElementwise(generateJsxAttributes(node), source, target, relation, containingMessageChain, errorOutputContainer);
2098420985 let invalidTextDiagnostic: DiagnosticMessage | undefined;
@@ -21092,7 +21093,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2109221093 target: Type,
2109321094 relation: Map<string, RelationComparisonResult>,
2109421095 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
21095- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
21096+ errorOutputContainer: ErrorOutputContainer | undefined,
2109621097 ) {
2109721098 if (target.flags & (TypeFlags.Primitive | TypeFlags.Never)) return false;
2109821099 if (isTupleLikeType(source)) {
@@ -21139,7 +21140,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2113921140 target: Type,
2114021141 relation: Map<string, RelationComparisonResult>,
2114121142 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
21142- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } | undefined,
21143+ errorOutputContainer: ErrorOutputContainer | undefined,
2114321144 ) {
2114421145 if (target.flags & (TypeFlags.Primitive | TypeFlags.Never)) return false;
2114521146 return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation, containingMessageChain, errorOutputContainer);
@@ -21637,7 +21638,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2163721638 errorNode: Node | undefined,
2163821639 headMessage?: DiagnosticMessage,
2163921640 containingMessageChain?: () => DiagnosticMessageChain | undefined,
21640- errorOutputContainer?: { errors?: Diagnostic[]; skipLogging?: boolean; } ,
21641+ errorOutputContainer?: ErrorOutputContainer ,
2164121642 ): boolean {
2164221643 let errorInfo: DiagnosticMessageChain | undefined;
2164321644 let relatedInfo: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined;
@@ -35186,7 +35187,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3518635187 checkMode: CheckMode,
3518735188 reportErrors: boolean,
3518835189 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
35189- errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } ,
35190+ errorOutputContainer: ErrorOutputContainer ,
3519035191 ) {
3519135192 // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
3519235193 // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
@@ -35302,7 +35303,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3530235303 containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
3530335304 inferenceContext: InferenceContext | undefined,
3530435305 ): readonly Diagnostic[] | undefined {
35305- const errorOutputContainer: { errors?: Diagnostic[]; skipLogging?: boolean; } = { errors: undefined, skipLogging: true };
35306+ const errorOutputContainer: ErrorOutputContainer = { errors: undefined, skipLogging: true };
3530635307 if (isJsxCallLike(node)) {
3530735308 if (!checkApplicableSignatureForJsxCallLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) {
3530835309 Debug.assert(!reportErrors || !!errorOutputContainer.errors, "jsx should have errors when reporting errors");
@@ -44934,7 +44935,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4493444935 }
4493544936
4493644937 if (!(type.flags & TypeFlags.Union)) {
44937- const errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined = errorNode ? { errors: undefined } : undefined;
44938+ const errorOutputContainer: ErrorOutputContainer | undefined = errorNode ? { errors: undefined, skipLogging: true } : undefined;
4493844939 const iterationTypes = getIterationTypesOfIterableWorker(type, use, errorNode, errorOutputContainer);
4493944940 if (iterationTypes === noIterationTypes) {
4494044941 if (errorNode) {
@@ -44959,7 +44960,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4495944960
4496044961 let allIterationTypes: IterationTypes[] | undefined;
4496144962 for (const constituent of (type as UnionType).types) {
44962- const errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined = errorNode ? { errors: undefined } : undefined;
44963+ const errorOutputContainer: ErrorOutputContainer | undefined = errorNode ? { errors: undefined } : undefined;
4496344964 const iterationTypes = getIterationTypesOfIterableWorker(constituent, use, errorNode, errorOutputContainer);
4496444965 if (iterationTypes === noIterationTypes) {
4496544966 if (errorNode) {
@@ -45010,7 +45011,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4501045011 * NOTE: You probably don't want to call this directly and should be calling
4501145012 * `getIterationTypesOfIterable` instead.
4501245013 */
45013- function getIterationTypesOfIterableWorker(type: Type, use: IterationUse, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined) {
45014+ function getIterationTypesOfIterableWorker(type: Type, use: IterationUse, errorNode: Node | undefined, errorOutputContainer: ErrorOutputContainer | undefined) {
4501445015 if (isTypeAny(type)) {
4501545016 return anyIterationTypes;
4501645017 }
@@ -45152,19 +45153,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4515245153 * NOTE: You probably don't want to call this directly and should be calling
4515345154 * `getIterationTypesOfIterable` instead.
4515445155 */
45155- function getIterationTypesOfIterableSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined, noCache: boolean) {
45156+ function getIterationTypesOfIterableSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: ErrorOutputContainer | undefined, noCache: boolean) {
4515645157 const method = getPropertyOfType(type, getPropertyNameForKnownSymbolName(resolver.iteratorSymbolName));
4515745158 const methodType = method && !(method.flags & SymbolFlags.Optional) ? getTypeOfSymbol(method) : undefined;
4515845159 if (isTypeAny(methodType)) {
4515945160 return noCache ? anyIterationTypes : setCachedIterationTypes(type, resolver.iterableCacheKey, anyIterationTypes);
4516045161 }
4516145162
45162- const signatures = methodType ? getSignaturesOfType(methodType, SignatureKind.Call) : undefined;
45163- if (!some(signatures)) {
45163+ const allSignatures = methodType ? getSignaturesOfType(methodType, SignatureKind.Call) : undefined;
45164+ const validSignatures = filter(allSignatures, sig => getMinArgumentCount(sig) === 0);
45165+ if (!some(validSignatures)) {
45166+ if (errorNode && some(allSignatures)) {
45167+ checkTypeAssignableTo(type, resolver.getGlobalIterableType(/*reportErrors*/ true), errorNode, /*headMessage*/ undefined, /*containingMessageChain*/ undefined, errorOutputContainer);
45168+ }
4516445169 return noCache ? noIterationTypes : setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes);
4516545170 }
4516645171
45167- const iteratorType = getIntersectionType(map(signatures , getReturnTypeOfSignature));
45172+ const iteratorType = getIntersectionType(map(validSignatures , getReturnTypeOfSignature));
4516845173 const iterationTypes = getIterationTypesOfIteratorWorker(iteratorType, resolver, errorNode, errorOutputContainer, noCache) ?? noIterationTypes;
4516945174 return noCache ? iterationTypes : setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes);
4517045175 }
@@ -45193,7 +45198,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4519345198 * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
4519445199 * record is returned. Otherwise, `undefined` is returned.
4519545200 */
45196- function getIterationTypesOfIterator(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined) {
45201+ function getIterationTypesOfIterator(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: ErrorOutputContainer | undefined) {
4519745202 return getIterationTypesOfIteratorWorker(type, resolver, errorNode, errorOutputContainer, /*noCache*/ false);
4519845203 }
4519945204
@@ -45206,7 +45211,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4520645211 * NOTE: You probably don't want to call this directly and should be calling
4520745212 * `getIterationTypesOfIterator` instead.
4520845213 */
45209- function getIterationTypesOfIteratorWorker(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined, noCache: boolean) {
45214+ function getIterationTypesOfIteratorWorker(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: ErrorOutputContainer | undefined, noCache: boolean) {
4521045215 if (isTypeAny(type)) {
4521145216 return anyIterationTypes;
4521245217 }
@@ -45348,7 +45353,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4534845353 * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
4534945354 * record is returned. Otherwise, we return `undefined`.
4535045355 */
45351- function getIterationTypesOfMethod(type: Type, resolver: IterationTypesResolver, methodName: "next" | "return" | "throw", errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined): IterationTypes | undefined {
45356+ function getIterationTypesOfMethod(type: Type, resolver: IterationTypesResolver, methodName: "next" | "return" | "throw", errorNode: Node | undefined, errorOutputContainer: ErrorOutputContainer | undefined): IterationTypes | undefined {
4535245357 const method = getPropertyOfType(type, methodName as __String);
4535345358
4535445359 // Ignore 'return' or 'throw' if they are missing.
@@ -45468,7 +45473,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4546845473 * NOTE: You probably don't want to call this directly and should be calling
4546945474 * `getIterationTypesOfIterator` instead.
4547045475 */
45471- function getIterationTypesOfIteratorSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined; } | undefined, noCache: boolean) {
45476+ function getIterationTypesOfIteratorSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: ErrorOutputContainer | undefined, noCache: boolean) {
4547245477 const iterationTypes = combineIterationTypes([
4547345478 getIterationTypesOfMethod(type, resolver, "next", errorNode, errorOutputContainer),
4547445479 getIterationTypesOfMethod(type, resolver, "return", errorNode, errorOutputContainer),
0 commit comments