diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7ac4bb7d5a52b..24f69aae21ab5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -38821,13 +38821,22 @@ namespace ts { } if (!(type.flags & TypeFlags.Union)) { - const iterationTypes = getIterationTypesOfIterableWorker(type, use, errorNode); + const errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined = errorNode ? { errors: undefined } : undefined; + const iterationTypes = getIterationTypesOfIterableWorker(type, use, errorNode, errorOutputContainer); if (iterationTypes === noIterationTypes) { if (errorNode) { - reportTypeNotIterableError(errorNode, type, !!(use & IterationUse.AllowsAsyncIterablesFlag)); + const rootDiag = reportTypeNotIterableError(errorNode, type, !!(use & IterationUse.AllowsAsyncIterablesFlag)); + if (errorOutputContainer?.errors) { + addRelatedInfo(rootDiag, ...errorOutputContainer.errors); + } } return undefined; } + else if (errorOutputContainer?.errors?.length) { + for (const diag of errorOutputContainer.errors) { + diagnostics.add(diag); + } + } return iterationTypes; } @@ -38837,17 +38846,25 @@ namespace ts { let allIterationTypes: IterationTypes[] | undefined; for (const constituent of (type as UnionType).types) { - const iterationTypes = getIterationTypesOfIterableWorker(constituent, use, errorNode); + const errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined = errorNode ? { errors: undefined } : undefined; + const iterationTypes = getIterationTypesOfIterableWorker(constituent, use, errorNode, errorOutputContainer); if (iterationTypes === noIterationTypes) { if (errorNode) { - reportTypeNotIterableError(errorNode, type, !!(use & IterationUse.AllowsAsyncIterablesFlag)); + const rootDiag = reportTypeNotIterableError(errorNode, type, !!(use & IterationUse.AllowsAsyncIterablesFlag)); + if (errorOutputContainer?.errors) { + addRelatedInfo(rootDiag, ...errorOutputContainer.errors); + } } setCachedIterationTypes(type, cacheKey, noIterationTypes); return undefined; } - else { - allIterationTypes = append(allIterationTypes, iterationTypes); + else if (errorOutputContainer?.errors?.length) { + for (const diag of errorOutputContainer.errors) { + diagnostics.add(diag); + } } + + allIterationTypes = append(allIterationTypes, iterationTypes); } const iterationTypes = allIterationTypes ? combineIterationTypes(allIterationTypes) : noIterationTypes; @@ -38879,53 +38896,69 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterable` instead. */ - function getIterationTypesOfIterableWorker(type: Type, use: IterationUse, errorNode: Node | undefined) { + function getIterationTypesOfIterableWorker(type: Type, use: IterationUse, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined) { if (isTypeAny(type)) { return anyIterationTypes; } + // If we are reporting errors and encounter a cached `noIterationTypes`, we should ignore the cached value and continue as if nothing was cached. + // In addition, we should not cache any new results for this call. + let noCache = false; + if (use & IterationUse.AllowsAsyncIterablesFlag) { const iterationTypes = getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) || getIterationTypesOfIterableFast(type, asyncIterationTypesResolver); if (iterationTypes) { - return use & IterationUse.ForOfFlag ? - getAsyncFromSyncIterationTypes(iterationTypes, errorNode) : - iterationTypes; + if (iterationTypes === noIterationTypes && errorNode) { + // ignore the cached value + noCache = true; + } + else { + return use & IterationUse.ForOfFlag ? + getAsyncFromSyncIterationTypes(iterationTypes, errorNode) : + iterationTypes; + } } } if (use & IterationUse.AllowsSyncIterablesFlag) { - const iterationTypes = + let iterationTypes = getIterationTypesOfIterableCached(type, syncIterationTypesResolver) || getIterationTypesOfIterableFast(type, syncIterationTypesResolver); if (iterationTypes) { - if (use & IterationUse.AllowsAsyncIterablesFlag) { - // for a sync iterable in an async context, only use the cached types if they are valid. - if (iterationTypes !== noIterationTypes) { - return setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", getAsyncFromSyncIterationTypes(iterationTypes, errorNode)); - } + if (iterationTypes === noIterationTypes && errorNode) { + // ignore the cached value + noCache = true; } else { - return iterationTypes; + if (use & IterationUse.AllowsAsyncIterablesFlag) { + // for a sync iterable in an async context, only use the cached types if they are valid. + if (iterationTypes !== noIterationTypes) { + iterationTypes = getAsyncFromSyncIterationTypes(iterationTypes, errorNode); + return noCache ? iterationTypes : setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", iterationTypes); + } + } + else { + return iterationTypes; + } } } } if (use & IterationUse.AllowsAsyncIterablesFlag) { - const iterationTypes = getIterationTypesOfIterableSlow(type, asyncIterationTypesResolver, errorNode); + const iterationTypes = getIterationTypesOfIterableSlow(type, asyncIterationTypesResolver, errorNode, errorOutputContainer, noCache); if (iterationTypes !== noIterationTypes) { return iterationTypes; } } if (use & IterationUse.AllowsSyncIterablesFlag) { - const iterationTypes = getIterationTypesOfIterableSlow(type, syncIterationTypesResolver, errorNode); + let iterationTypes = getIterationTypesOfIterableSlow(type, syncIterationTypesResolver, errorNode, errorOutputContainer, noCache); if (iterationTypes !== noIterationTypes) { if (use & IterationUse.AllowsAsyncIterablesFlag) { - return setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", iterationTypes - ? getAsyncFromSyncIterationTypes(iterationTypes, errorNode) - : noIterationTypes); + iterationTypes = getAsyncFromSyncIterationTypes(iterationTypes, errorNode); + return noCache ? iterationTypes : setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", iterationTypes); } else { return iterationTypes; @@ -38950,7 +38983,7 @@ namespace ts { function getIterationTypesOfGlobalIterableType(globalType: Type, resolver: IterationTypesResolver) { const globalIterationTypes = getIterationTypesOfIterableCached(globalType, resolver) || - getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined); + getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined, /*errorOutputContainer*/ undefined, /*noCache*/ false); return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes; } @@ -39008,28 +39041,28 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterable` instead. */ - function getIterationTypesOfIterableSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined) { + function getIterationTypesOfIterableSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined, noCache: boolean) { const method = getPropertyOfType(type, getPropertyNameForKnownSymbolName(resolver.iteratorSymbolName)); const methodType = method && !(method.flags & SymbolFlags.Optional) ? getTypeOfSymbol(method) : undefined; if (isTypeAny(methodType)) { - return setCachedIterationTypes(type, resolver.iterableCacheKey, anyIterationTypes); + return noCache ? anyIterationTypes : setCachedIterationTypes(type, resolver.iterableCacheKey, anyIterationTypes); } const signatures = methodType ? getSignaturesOfType(methodType, SignatureKind.Call) : undefined; if (!some(signatures)) { - return setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes); + return noCache ? noIterationTypes : setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes); } const iteratorType = getIntersectionType(map(signatures, getReturnTypeOfSignature)); - const iterationTypes = getIterationTypesOfIterator(iteratorType, resolver, errorNode) ?? noIterationTypes; - return setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes); + const iterationTypes = getIterationTypesOfIteratorWorker(iteratorType, resolver, errorNode, errorOutputContainer, noCache) ?? noIterationTypes; + return noCache ? iterationTypes : setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes); } - function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void { + function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): Diagnostic { const message = allowAsyncIterables ? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator : Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator; - errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type)); + return errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type)); } /** @@ -39038,15 +39071,34 @@ namespace ts { * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes` * record is returned. Otherwise, `undefined` is returned. */ - function getIterationTypesOfIterator(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined) { + function getIterationTypesOfIterator(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined) { + return getIterationTypesOfIteratorWorker(type, resolver, errorNode, errorOutputContainer, /*noCache*/ false); + } + + /** + * Gets the *yield*, *return*, and *next* types from an `Iterator`-like or `AsyncIterator`-like type. + * + * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes` + * record is returned. Otherwise, `undefined` is returned. + * + * NOTE: You probably don't want to call this directly and should be calling + * `getIterationTypesOfIterator` instead. + */ + function getIterationTypesOfIteratorWorker(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined, noCache: boolean) { if (isTypeAny(type)) { return anyIterationTypes; } - const iterationTypes = + let iterationTypes = getIterationTypesOfIteratorCached(type, resolver) || - getIterationTypesOfIteratorFast(type, resolver) || - getIterationTypesOfIteratorSlow(type, resolver, errorNode); + getIterationTypesOfIteratorFast(type, resolver); + + if (iterationTypes === noIterationTypes && errorNode) { + iterationTypes = undefined; + noCache = true; + } + + iterationTypes ??= getIterationTypesOfIteratorSlow(type, resolver, errorNode, errorOutputContainer, noCache); return iterationTypes === noIterationTypes ? undefined : iterationTypes; } @@ -39087,7 +39139,7 @@ namespace ts { // and `undefined` in our libs by default, a custom lib *could* use different definitions. const globalIterationTypes = getIterationTypesOfIteratorCached(globalType, resolver) || - getIterationTypesOfIteratorSlow(globalType, resolver, /*errorNode*/ undefined); + getIterationTypesOfIteratorSlow(globalType, resolver, /*errorNode*/ undefined, /*errorOutputContainer*/ undefined, /*noCache*/ false); const { returnType, nextType } = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes; return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType)); } @@ -39168,7 +39220,7 @@ namespace ts { * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes` * record is returned. Otherwise, we return `undefined`. */ - function getIterationTypesOfMethod(type: Type, resolver: IterationTypesResolver, methodName: "next" | "return" | "throw", errorNode: Node | undefined): IterationTypes | undefined { + function getIterationTypesOfMethod(type: Type, resolver: IterationTypesResolver, methodName: "next" | "return" | "throw", errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined): IterationTypes | undefined { const method = getPropertyOfType(type, methodName as __String); // Ignore 'return' or 'throw' if they are missing. @@ -39192,9 +39244,15 @@ namespace ts { const diagnostic = methodName === "next" ? resolver.mustHaveANextMethodDiagnostic : resolver.mustBeAMethodDiagnostic; - error(errorNode, diagnostic, methodName); + if (errorOutputContainer) { + errorOutputContainer.errors ??= []; + errorOutputContainer.errors.push(createDiagnosticForNode(errorNode, diagnostic, methodName)); + } + else { + error(errorNode, diagnostic, methodName); + } } - return methodName === "next" ? anyIterationTypes : undefined; + return methodName === "next" ? noIterationTypes : undefined; } // If the method signature comes exclusively from the global iterator or generator type, @@ -39253,7 +39311,13 @@ namespace ts { const iterationTypes = getIterationTypesOfIteratorResult(resolvedMethodReturnType); if (iterationTypes === noIterationTypes) { if (errorNode) { - error(errorNode, resolver.mustHaveAValueDiagnostic, methodName); + if (errorOutputContainer) { + errorOutputContainer.errors ??= []; + errorOutputContainer.errors.push(createDiagnosticForNode(errorNode, resolver.mustHaveAValueDiagnostic, methodName)); + } + else { + error(errorNode, resolver.mustHaveAValueDiagnostic, methodName); + } } yieldType = anyType; returnTypes = append(returnTypes, anyType); @@ -39276,13 +39340,13 @@ namespace ts { * NOTE: You probably don't want to call this directly and should be calling * `getIterationTypesOfIterator` instead. */ - function getIterationTypesOfIteratorSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined) { + function getIterationTypesOfIteratorSlow(type: Type, resolver: IterationTypesResolver, errorNode: Node | undefined, errorOutputContainer: { errors: Diagnostic[] | undefined } | undefined, noCache: boolean) { const iterationTypes = combineIterationTypes([ - getIterationTypesOfMethod(type, resolver, "next", errorNode), - getIterationTypesOfMethod(type, resolver, "return", errorNode), - getIterationTypesOfMethod(type, resolver, "throw", errorNode), + getIterationTypesOfMethod(type, resolver, "next", errorNode, errorOutputContainer), + getIterationTypesOfMethod(type, resolver, "return", errorNode, errorOutputContainer), + getIterationTypesOfMethod(type, resolver, "throw", errorNode, errorOutputContainer), ]); - return setCachedIterationTypes(type, resolver.iteratorCacheKey, iterationTypes); + return noCache ? iterationTypes : setCachedIterationTypes(type, resolver.iteratorCacheKey, iterationTypes); } /** @@ -39307,7 +39371,7 @@ namespace ts { const use = isAsyncGenerator ? IterationUse.AsyncGeneratorReturnType : IterationUse.GeneratorReturnType; const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver; return getIterationTypesOfIterable(type, use, /*errorNode*/ undefined) || - getIterationTypesOfIterator(type, resolver, /*errorNode*/ undefined); + getIterationTypesOfIterator(type, resolver, /*errorNode*/ undefined, /*errorOutputContainer*/ undefined); } function checkBreakOrContinueStatement(node: BreakOrContinueStatement) { diff --git a/tests/baselines/reference/for-of16.errors.txt b/tests/baselines/reference/for-of16.errors.txt index 7574f98e3d8a8..2c53681eaaadf 100644 --- a/tests/baselines/reference/for-of16.errors.txt +++ b/tests/baselines/reference/for-of16.errors.txt @@ -1,7 +1,8 @@ -tests/cases/conformance/es6/for-ofStatements/for-of16.ts(8,11): error TS2489: An iterator must have a 'next()' method. +tests/cases/conformance/es6/for-ofStatements/for-of16.ts(8,11): error TS2488: Type 'StringIterator' must have a '[Symbol.iterator]()' method that returns an iterator. +tests/cases/conformance/es6/for-ofStatements/for-of16.ts(10,11): error TS2488: Type 'StringIterator' must have a '[Symbol.iterator]()' method that returns an iterator. -==== tests/cases/conformance/es6/for-ofStatements/for-of16.ts (1 errors) ==== +==== tests/cases/conformance/es6/for-ofStatements/for-of16.ts (2 errors) ==== class StringIterator { [Symbol.iterator]() { return this; @@ -11,4 +12,10 @@ tests/cases/conformance/es6/for-ofStatements/for-of16.ts(8,11): error TS2489: An var v: string; for (v of new StringIterator) { } // Should fail ~~~~~~~~~~~~~~~~~~ -!!! error TS2489: An iterator must have a 'next()' method. \ No newline at end of file +!!! error TS2488: Type 'StringIterator' must have a '[Symbol.iterator]()' method that returns an iterator. +!!! related TS2489 tests/cases/conformance/es6/for-ofStatements/for-of16.ts:8:11: An iterator must have a 'next()' method. + + for (v of new StringIterator) { } // Should still fail (related errors should still be shown even though type is cached). + ~~~~~~~~~~~~~~~~~~ +!!! error TS2488: Type 'StringIterator' must have a '[Symbol.iterator]()' method that returns an iterator. +!!! related TS2489 tests/cases/conformance/es6/for-ofStatements/for-of16.ts:10:11: An iterator must have a 'next()' method. \ No newline at end of file diff --git a/tests/baselines/reference/for-of16.js b/tests/baselines/reference/for-of16.js index 2219e15a6f92a..b0ccae1d413c7 100644 --- a/tests/baselines/reference/for-of16.js +++ b/tests/baselines/reference/for-of16.js @@ -6,7 +6,9 @@ class StringIterator { } var v: string; -for (v of new StringIterator) { } // Should fail +for (v of new StringIterator) { } // Should fail + +for (v of new StringIterator) { } // Should still fail (related errors should still be shown even though type is cached). //// [for-of16.js] class StringIterator { @@ -16,3 +18,4 @@ class StringIterator { } var v; for (v of new StringIterator) { } // Should fail +for (v of new StringIterator) { } // Should still fail (related errors should still be shown even though type is cached). diff --git a/tests/baselines/reference/for-of16.symbols b/tests/baselines/reference/for-of16.symbols index 1bd52fa5dc6c3..53b1f78ae01f2 100644 --- a/tests/baselines/reference/for-of16.symbols +++ b/tests/baselines/reference/for-of16.symbols @@ -20,3 +20,7 @@ for (v of new StringIterator) { } // Should fail >v : Symbol(v, Decl(for-of16.ts, 6, 3)) >StringIterator : Symbol(StringIterator, Decl(for-of16.ts, 0, 0)) +for (v of new StringIterator) { } // Should still fail (related errors should still be shown even though type is cached). +>v : Symbol(v, Decl(for-of16.ts, 6, 3)) +>StringIterator : Symbol(StringIterator, Decl(for-of16.ts, 0, 0)) + diff --git a/tests/baselines/reference/for-of16.types b/tests/baselines/reference/for-of16.types index 2fb955fec59ff..155db0d74198a 100644 --- a/tests/baselines/reference/for-of16.types +++ b/tests/baselines/reference/for-of16.types @@ -21,3 +21,8 @@ for (v of new StringIterator) { } // Should fail >new StringIterator : StringIterator >StringIterator : typeof StringIterator +for (v of new StringIterator) { } // Should still fail (related errors should still be shown even though type is cached). +>v : string +>new StringIterator : StringIterator +>StringIterator : typeof StringIterator + diff --git a/tests/baselines/reference/generatorTypeCheck31.errors.txt b/tests/baselines/reference/generatorTypeCheck31.errors.txt index 9aaf3b745ee4e..0ed5dcbe0e08f 100644 --- a/tests/baselines/reference/generatorTypeCheck31.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck31.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck31.ts(2,11): error TS2322: Type 'Generator<(x: any) => any, void, any>' is not assignable to type '() => Iterable<(x: string) => number>'. - Type 'Generator<(x: any) => any, void, any>' provides no match for the signature '(): Iterable<(x: string) => number>'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck31.ts(2,11): error TS2322: Type 'Generator<(x: any) => any, void, unknown>' is not assignable to type '() => Iterable<(x: string) => number>'. + Type 'Generator<(x: any) => any, void, unknown>' provides no match for the signature '(): Iterable<(x: string) => number>'. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck31.ts (1 errors) ==== @@ -10,6 +10,6 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck31.ts(2,11): erro ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } () ~~~~~~~~ -!!! error TS2322: Type 'Generator<(x: any) => any, void, any>' is not assignable to type '() => Iterable<(x: string) => number>'. -!!! error TS2322: Type 'Generator<(x: any) => any, void, any>' provides no match for the signature '(): Iterable<(x: string) => number>'. +!!! error TS2322: Type 'Generator<(x: any) => any, void, unknown>' is not assignable to type '() => Iterable<(x: string) => number>'. +!!! error TS2322: Type 'Generator<(x: any) => any, void, unknown>' provides no match for the signature '(): Iterable<(x: string) => number>'. } \ No newline at end of file diff --git a/tests/baselines/reference/generatorTypeCheck31.types b/tests/baselines/reference/generatorTypeCheck31.types index 2a3828322fffb..c15eab96fe9e0 100644 --- a/tests/baselines/reference/generatorTypeCheck31.types +++ b/tests/baselines/reference/generatorTypeCheck31.types @@ -5,8 +5,8 @@ function* g2(): Iterator<() => Iterable<(x: string) => number>> { yield function* () { >yield function* () { yield x => x.length; } () : undefined ->function* () { yield x => x.length; } () : Generator<(x: any) => any, void, any> ->function* () { yield x => x.length; } : () => Generator<(x: any) => any, void, any> +>function* () { yield x => x.length; } () : Generator<(x: any) => any, void, unknown> +>function* () { yield x => x.length; } : () => Generator<(x: any) => any, void, unknown> yield x => x.length; >yield x => x.length : any diff --git a/tests/baselines/reference/generatorTypeCheck6.errors.txt b/tests/baselines/reference/generatorTypeCheck6.errors.txt index a9eca26ca4f65..7084844c48ffa 100644 --- a/tests/baselines/reference/generatorTypeCheck6.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck6.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck6.ts(1,17): error TS2322: Type 'Generator' is not assignable to type 'number'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck6.ts(1,17): error TS2322: Type 'Generator' is not assignable to type 'number'. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck6.ts (1 errors) ==== function* g1(): number { } ~~~~~~ -!!! error TS2322: Type 'Generator' is not assignable to type 'number'. \ No newline at end of file +!!! error TS2322: Type 'Generator' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray10.errors.txt b/tests/baselines/reference/iteratorSpreadInArray10.errors.txt index 28a878ac4319a..00cc1017990bf 100644 --- a/tests/baselines/reference/iteratorSpreadInArray10.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray10.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts(7,17): error TS2489: An iterator must have a 'next()' method. +tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts(7,17): error TS2488: Type 'SymbolIterator' must have a '[Symbol.iterator]()' method that returns an iterator. ==== tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts (1 errors) ==== @@ -10,4 +10,5 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts(7,17): error TS248 var array = [...new SymbolIterator]; ~~~~~~~~~~~~~~~~~~ -!!! error TS2489: An iterator must have a 'next()' method. \ No newline at end of file +!!! error TS2488: Type 'SymbolIterator' must have a '[Symbol.iterator]()' method that returns an iterator. +!!! related TS2489 tests/cases/conformance/es6/spread/iteratorSpreadInArray10.ts:7:17: An iterator must have a 'next()' method. \ No newline at end of file diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index c2b79942f2950..520c23ed384cb 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -36,7 +36,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(59,12): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(62,12): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(64,42): error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'IterableIterator'. -tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(67,42): error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'Iterable'. +tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(67,42): error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'Iterable'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(70,42): error TS2322: Type 'AsyncGenerator' is not assignable to type 'Iterator'. The types returned by 'next(...)' are incompatible between these types. Type 'Promise>' is not assignable to type 'IteratorResult'. @@ -173,7 +173,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( } async function * explicitReturnType11(): Iterable { ~~~~~~~~~~~~~~~~ -!!! error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'Iterable'. +!!! error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'Iterable'. !!! related TS2728 /.ts/lib.es2015.iterable.d.ts:51:5: '[Symbol.iterator]' is declared here. yield 1; } diff --git a/tests/cases/conformance/es6/for-ofStatements/for-of16.ts b/tests/cases/conformance/es6/for-ofStatements/for-of16.ts index fe78bae2aefad..b63e061425ee9 100644 --- a/tests/cases/conformance/es6/for-ofStatements/for-of16.ts +++ b/tests/cases/conformance/es6/for-ofStatements/for-of16.ts @@ -6,4 +6,6 @@ class StringIterator { } var v: string; -for (v of new StringIterator) { } // Should fail \ No newline at end of file +for (v of new StringIterator) { } // Should fail + +for (v of new StringIterator) { } // Should still fail (related errors should still be shown even though type is cached). \ No newline at end of file