mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 07:45:18 -06:00
Fall back to (Async)IterableIterator if (Async)Generator not found (#32303)
This commit is contained in:
parent
0038b0baa3
commit
17762c480d
@ -42,10 +42,10 @@ namespace ts {
|
||||
iterableCacheKey: "iterationTypesOfAsyncIterable" | "iterationTypesOfIterable";
|
||||
iteratorCacheKey: "iterationTypesOfAsyncIterator" | "iterationTypesOfIterator";
|
||||
iteratorSymbolName: "asyncIterator" | "iterator";
|
||||
getGlobalIteratorType: (reportErrors: boolean) => Type;
|
||||
getGlobalIterableType: (reportErrors: boolean) => Type;
|
||||
getGlobalIterableIteratorType: (reportErrors: boolean) => Type;
|
||||
getGlobalGeneratorType: (reportErrors: boolean) => Type;
|
||||
getGlobalIteratorType: (reportErrors: boolean) => GenericType;
|
||||
getGlobalIterableType: (reportErrors: boolean) => GenericType;
|
||||
getGlobalIterableIteratorType: (reportErrors: boolean) => GenericType;
|
||||
getGlobalGeneratorType: (reportErrors: boolean) => GenericType;
|
||||
resolveIterationType: (type: Type, errorNode: Node | undefined) => Type | undefined;
|
||||
mustHaveANextMethodDiagnostic: DiagnosticMessage;
|
||||
mustBeAMethodDiagnostic: DiagnosticMessage;
|
||||
@ -9531,24 +9531,10 @@ namespace ts {
|
||||
return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
|
||||
}
|
||||
|
||||
function createAsyncGeneratorType(yieldType: Type, returnType: Type, nextType: Type) {
|
||||
const globalAsyncGeneratorType = getGlobalAsyncGeneratorType(/*reportErrors*/ true);
|
||||
if (globalAsyncGeneratorType !== emptyGenericType) {
|
||||
yieldType = getAwaitedType(yieldType) || unknownType;
|
||||
returnType = getAwaitedType(returnType) || unknownType;
|
||||
nextType = getAwaitedType(nextType) || unknownType;
|
||||
}
|
||||
return createTypeFromGenericGlobalType(globalAsyncGeneratorType, [yieldType, returnType, nextType]);
|
||||
}
|
||||
|
||||
function createIterableType(iteratedType: Type): Type {
|
||||
return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
|
||||
}
|
||||
|
||||
function createGeneratorType(yieldType: Type, returnType: Type, nextType: Type) {
|
||||
return createTypeFromGenericGlobalType(getGlobalGeneratorType(/*reportErrors*/ true), [yieldType, returnType, nextType]);
|
||||
}
|
||||
|
||||
function createArrayType(elementType: Type, readonly?: boolean): ObjectType {
|
||||
return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
|
||||
}
|
||||
@ -23401,9 +23387,36 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
|
||||
return isAsyncGenerator
|
||||
? createAsyncGeneratorType(yieldType, returnType, nextType)
|
||||
: createGeneratorType(yieldType, returnType, nextType);
|
||||
const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
|
||||
const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
|
||||
yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
|
||||
returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType;
|
||||
nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType;
|
||||
if (globalGeneratorType === emptyGenericType) {
|
||||
// Fall back to the global IterableIterator if returnType is assignable to the expected return iteration
|
||||
// type of IterableIterator, and the expected next iteration type of IterableIterator is assignable to
|
||||
// nextType.
|
||||
const globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
|
||||
const iterationTypes = globalType !== emptyGenericType ? getIterationTypesOfGlobalIterableType(globalType, resolver) : undefined;
|
||||
const iterableIteratorReturnType = iterationTypes ? iterationTypes.returnType : anyType;
|
||||
const iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : undefinedType;
|
||||
if (isTypeAssignableTo(returnType, iterableIteratorReturnType) &&
|
||||
isTypeAssignableTo(iterableIteratorNextType, nextType)) {
|
||||
if (globalType !== emptyGenericType) {
|
||||
return createTypeFromGenericGlobalType(globalType, [yieldType]);
|
||||
}
|
||||
|
||||
// The global IterableIterator type doesn't exist, so report an error
|
||||
resolver.getGlobalIterableIteratorType(/*reportErrors*/ true);
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
// The global Generator type doesn't exist, so report an error
|
||||
resolver.getGlobalGeneratorType(/*reportErrors*/ true);
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
return createTypeFromGenericGlobalType(globalGeneratorType, [yieldType, returnType, nextType]);
|
||||
}
|
||||
|
||||
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode | undefined) {
|
||||
@ -28240,6 +28253,13 @@ namespace ts {
|
||||
return (type as IterableOrIteratorType)[resolver.iterableCacheKey];
|
||||
}
|
||||
|
||||
function getIterationTypesOfGlobalIterableType(globalType: Type, resolver: IterationTypesResolver) {
|
||||
const globalIterationTypes =
|
||||
getIterationTypesOfIterableCached(globalType, resolver) ||
|
||||
getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
|
||||
return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
|
||||
* type from from common heuristics.
|
||||
@ -28265,10 +28285,7 @@ namespace ts {
|
||||
// iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins.
|
||||
// While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
|
||||
// different definitions.
|
||||
const globalIterationTypes =
|
||||
getIterationTypesOfIterableCached(globalType, resolver) ||
|
||||
getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
|
||||
const { returnType, nextType } = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
|
||||
const { returnType, nextType } = getIterationTypesOfGlobalIterableType(globalType, resolver);
|
||||
return (type as IterableOrIteratorType)[resolver.iterableCacheKey] = createIterationTypes(yieldType, returnType, nextType);
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
error TS2318: Cannot find global type 'Generator'.
|
||||
error TS2318: Cannot find global type 'IterableIterator'.
|
||||
tests/cases/compiler/castOfYield.ts(4,14): error TS1109: Expression expected.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'Generator'.
|
||||
!!! error TS2318: Cannot find global type 'IterableIterator'.
|
||||
==== tests/cases/compiler/castOfYield.ts (1 errors) ====
|
||||
function* f() {
|
||||
<number> (yield 0);
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.1.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
function* f() {
|
||||
>f : Symbol(f, Decl(generatorReturnTypeFallback.1.ts, 0, 0))
|
||||
|
||||
yield 1;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.1.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
function* f() {
|
||||
>f : () => IterableIterator<number>
|
||||
|
||||
yield 1;
|
||||
>yield 1 : any
|
||||
>1 : 1
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
error TS2318: Cannot find global type 'IterableIterator'.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'IterableIterator'.
|
||||
==== tests/cases/conformance/generators/generatorReturnTypeFallback.2.ts (0 errors) ====
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
// Report an error if IterableIterator cannot be found.
|
||||
function* f() {
|
||||
yield 1;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.2.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
// Report an error if IterableIterator cannot be found.
|
||||
function* f() {
|
||||
>f : Symbol(f, Decl(generatorReturnTypeFallback.2.ts, 0, 0))
|
||||
|
||||
yield 1;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.2.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
// Report an error if IterableIterator cannot be found.
|
||||
function* f() {
|
||||
>f : () => {}
|
||||
|
||||
yield 1;
|
||||
>yield 1 : any
|
||||
>1 : 1
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
error TS2318: Cannot find global type 'Generator'.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'Generator'.
|
||||
==== tests/cases/conformance/generators/generatorReturnTypeFallback.3.ts (0 errors) ====
|
||||
// Do not allow generators to fallback to IterableIterator while in strictNullChecks mode if they need a type for the sent value.
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
const x: string = yield 1;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.3.ts ===
|
||||
// Do not allow generators to fallback to IterableIterator while in strictNullChecks mode if they need a type for the sent value.
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
>f : Symbol(f, Decl(generatorReturnTypeFallback.3.ts, 0, 0))
|
||||
|
||||
const x: string = yield 1;
|
||||
>x : Symbol(x, Decl(generatorReturnTypeFallback.3.ts, 3, 9))
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.3.ts ===
|
||||
// Do not allow generators to fallback to IterableIterator while in strictNullChecks mode if they need a type for the sent value.
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
>f : () => {}
|
||||
|
||||
const x: string = yield 1;
|
||||
>x : string
|
||||
>yield 1 : any
|
||||
>1 : 1
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.4.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they are not in strictNullChecks mode
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
>f : Symbol(f, Decl(generatorReturnTypeFallback.4.ts, 0, 0))
|
||||
|
||||
const x: string = yield 1;
|
||||
>x : Symbol(x, Decl(generatorReturnTypeFallback.4.ts, 3, 9))
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.4.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they are not in strictNullChecks mode
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
>f : () => IterableIterator<number>
|
||||
|
||||
const x: string = yield 1;
|
||||
>x : string
|
||||
>yield 1 : any
|
||||
>1 : 1
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.5.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
function* f(): IterableIterator<number> {
|
||||
>f : Symbol(f, Decl(generatorReturnTypeFallback.5.ts, 0, 0))
|
||||
>IterableIterator : Symbol(IterableIterator, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
|
||||
yield 1;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/generators/generatorReturnTypeFallback.5.ts ===
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
function* f(): IterableIterator<number> {
|
||||
>f : () => IterableIterator<number>
|
||||
|
||||
yield 1;
|
||||
>yield 1 : undefined
|
||||
>1 : 1
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
error TS2318: Cannot find global type 'Generator'.
|
||||
error TS2318: Cannot find global type 'IterableIterator'.
|
||||
tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): error TS2554: Expected 2 arguments, but got 1.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'Generator'.
|
||||
!!! error TS2318: Cannot find global type 'IterableIterator'.
|
||||
==== tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts (1 errors) ====
|
||||
declare function call<Fn extends (...args: any[]) => any>(
|
||||
fn: Fn,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
error TS2318: Cannot find global type 'Generator'.
|
||||
error TS2318: Cannot find global type 'IterableIterator'.
|
||||
tests/cases/conformance/es6/templates/templateStringWithEmbeddedYieldKeyword.ts(1,15): error TS1005: '(' expected.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'Generator'.
|
||||
!!! error TS2318: Cannot find global type 'IterableIterator'.
|
||||
==== tests/cases/conformance/es6/templates/templateStringWithEmbeddedYieldKeyword.ts (1 errors) ====
|
||||
function* gen {
|
||||
~
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
error TS2318: Cannot find global type 'AsyncGenerator'.
|
||||
error TS2318: Cannot find global type 'AsyncIterableIterator'.
|
||||
tests/cases/conformance/types/forAwait/types.forAwait.es2018.3.ts(3,27): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.
|
||||
tests/cases/conformance/types/forAwait/types.forAwait.es2018.3.ts(5,21): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.
|
||||
tests/cases/conformance/types/forAwait/types.forAwait.es2018.3.ts(10,27): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.
|
||||
tests/cases/conformance/types/forAwait/types.forAwait.es2018.3.ts(12,21): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'AsyncGenerator'.
|
||||
!!! error TS2318: Cannot find global type 'AsyncIterableIterator'.
|
||||
==== tests/cases/conformance/types/forAwait/types.forAwait.es2018.3.ts (4 errors) ====
|
||||
async function f1() {
|
||||
let y: number;
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
// @target: esnext
|
||||
// @lib: es5,es2015.iterable
|
||||
// @noemit: true
|
||||
// @strict: true
|
||||
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
function* f() {
|
||||
yield 1;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
// @target: esnext
|
||||
// @lib: es5
|
||||
// @noemit: true
|
||||
// @strict: true
|
||||
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
// Report an error if IterableIterator cannot be found.
|
||||
function* f() {
|
||||
yield 1;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
// @target: esnext
|
||||
// @lib: es5,es2015.iterable
|
||||
// @noemit: true
|
||||
// @strict: true
|
||||
|
||||
// Do not allow generators to fallback to IterableIterator while in strictNullChecks mode if they need a type for the sent value.
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
const x: string = yield 1;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
// @target: esnext
|
||||
// @lib: es5,es2015.iterable
|
||||
// @noemit: true
|
||||
// @strict: false
|
||||
|
||||
// Allow generators to fallback to IterableIterator if they are not in strictNullChecks mode
|
||||
// NOTE: In non-strictNullChecks mode, `undefined` (the default sent value) is assignable to everything.
|
||||
function* f() {
|
||||
const x: string = yield 1;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
// @target: esnext
|
||||
// @lib: es5,es2015.iterable
|
||||
// @noemit: true
|
||||
// @strict: true
|
||||
|
||||
// Allow generators to fallback to IterableIterator if they do not need a type for the sent value while in strictNullChecks mode.
|
||||
function* f(): IterableIterator<number> {
|
||||
yield 1;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user