mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Use Awaited<T> with 'await'
This commit is contained in:
1 parent
46ce88c565
commit
5bdae61bb2
8 files changed
+192
-89
No files matched your search
+168
-67
@@ -904,28 +904,29 @@ namespace ts {
|
||||
// and they will not get an error from not having unrelated library files
|
||||
let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined;
|
||||
let deferredGlobalESSymbolConstructorTypeSymbol: Symbol | undefined;
|
||||
let deferredGlobalESSymbolType: ObjectType;
|
||||
let deferredGlobalESSymbolType: ObjectType | undefined;
|
||||
let deferredGlobalTypedPropertyDescriptorType: GenericType;
|
||||
let deferredGlobalPromiseType: GenericType;
|
||||
let deferredGlobalPromiseLikeType: GenericType;
|
||||
let deferredGlobalPromiseType: GenericType | undefined;
|
||||
let deferredGlobalPromiseLikeType: GenericType | undefined;
|
||||
let deferredGlobalPromiseConstructorSymbol: Symbol | undefined;
|
||||
let deferredGlobalPromiseConstructorLikeType: ObjectType;
|
||||
let deferredGlobalIterableType: GenericType;
|
||||
let deferredGlobalIteratorType: GenericType;
|
||||
let deferredGlobalIterableIteratorType: GenericType;
|
||||
let deferredGlobalGeneratorType: GenericType;
|
||||
let deferredGlobalIteratorYieldResultType: GenericType;
|
||||
let deferredGlobalIteratorReturnResultType: GenericType;
|
||||
let deferredGlobalAsyncIterableType: GenericType;
|
||||
let deferredGlobalAsyncIteratorType: GenericType;
|
||||
let deferredGlobalAsyncIterableIteratorType: GenericType;
|
||||
let deferredGlobalAsyncGeneratorType: GenericType;
|
||||
let deferredGlobalTemplateStringsArrayType: ObjectType;
|
||||
let deferredGlobalPromiseConstructorLikeType: ObjectType | undefined;
|
||||
let deferredGlobalIterableType: GenericType | undefined;
|
||||
let deferredGlobalIteratorType: GenericType | undefined;
|
||||
let deferredGlobalIterableIteratorType: GenericType | undefined;
|
||||
let deferredGlobalGeneratorType: GenericType | undefined;
|
||||
let deferredGlobalIteratorYieldResultType: GenericType | undefined;
|
||||
let deferredGlobalIteratorReturnResultType: GenericType | undefined;
|
||||
let deferredGlobalAsyncIterableType: GenericType | undefined;
|
||||
let deferredGlobalAsyncIteratorType: GenericType | undefined;
|
||||
let deferredGlobalAsyncIterableIteratorType: GenericType | undefined;
|
||||
let deferredGlobalAsyncGeneratorType: GenericType | undefined;
|
||||
let deferredGlobalTemplateStringsArrayType: ObjectType | undefined;
|
||||
let deferredGlobalImportMetaType: ObjectType;
|
||||
let deferredGlobalImportMetaExpressionType: ObjectType;
|
||||
let deferredGlobalExtractSymbol: Symbol;
|
||||
let deferredGlobalOmitSymbol: Symbol;
|
||||
let deferredGlobalBigIntType: ObjectType;
|
||||
let deferredGlobalExtractSymbol: Symbol | undefined;
|
||||
let deferredGlobalOmitSymbol: Symbol | undefined;
|
||||
let deferredGlobalAwaitedSymbol: Symbol | undefined;
|
||||
let deferredGlobalBigIntType: ObjectType | undefined;
|
||||
|
||||
const allPotentiallyUnusedIdentifiers = new Map<Path, PotentiallyUnusedIdentifier[]>(); // key is file name
|
||||
|
||||
@@ -13320,28 +13321,48 @@ namespace ts {
|
||||
return getGlobalSymbol(name, SymbolFlags.Type, reportErrors ? Diagnostics.Cannot_find_global_type_0 : undefined);
|
||||
}
|
||||
|
||||
function getGlobalTypeAliasSymbol(name: __String, arity: number, reportErrors: boolean): Symbol | undefined {
|
||||
const symbol = getGlobalSymbol(name, SymbolFlags.Type, reportErrors ? Diagnostics.Cannot_find_global_type_0 : undefined);
|
||||
if (symbol) {
|
||||
// Resolve the declared type of the symbol. This resolves type parameters for the type
|
||||
// alias so that we can check arity.
|
||||
getDeclaredTypeOfSymbol(symbol);
|
||||
if (length(getSymbolLinks(symbol).typeParameters) !== arity) {
|
||||
const decl = symbol.declarations && find(symbol.declarations, isTypeAliasDeclaration);
|
||||
error(decl, Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbolName(symbol), arity);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
function getGlobalSymbol(name: __String, meaning: SymbolFlags, diagnostic: DiagnosticMessage | undefined): Symbol | undefined {
|
||||
// Don't track references for global symbols anyway, so value if `isReference` is arbitrary
|
||||
return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false);
|
||||
}
|
||||
|
||||
function getGlobalType(name: __String, arity: 0, reportErrors: boolean): ObjectType;
|
||||
function getGlobalType(name: __String, arity: number, reportErrors: boolean): GenericType;
|
||||
function getGlobalType(name: __String, arity: 0, reportErrors: true): ObjectType;
|
||||
function getGlobalType(name: __String, arity: 0, reportErrors: boolean): ObjectType | undefined;
|
||||
function getGlobalType(name: __String, arity: number, reportErrors: true): GenericType;
|
||||
function getGlobalType(name: __String, arity: number, reportErrors: boolean): GenericType | undefined;
|
||||
function getGlobalType(name: __String, arity: number, reportErrors: boolean): ObjectType | undefined {
|
||||
const symbol = getGlobalTypeSymbol(name, reportErrors);
|
||||
return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined;
|
||||
}
|
||||
|
||||
function getGlobalTypedPropertyDescriptorType() {
|
||||
return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor" as __String, /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType;
|
||||
// We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times
|
||||
return deferredGlobalTypedPropertyDescriptorType ||= getGlobalType("TypedPropertyDescriptor" as __String, /*arity*/ 1, /*reportErrors*/ true) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalTemplateStringsArrayType() {
|
||||
return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
|
||||
// We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times
|
||||
return deferredGlobalTemplateStringsArrayType ||= getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType;
|
||||
}
|
||||
|
||||
function getGlobalImportMetaType() {
|
||||
return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
|
||||
// We always report an error, so store a result in the event we could not resolve the symbol to prevent reporting it multiple times
|
||||
return deferredGlobalImportMetaType ||= getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true) || emptyObjectType;
|
||||
}
|
||||
|
||||
function getGlobalImportMetaExpressionType() {
|
||||
@@ -13362,72 +13383,72 @@ namespace ts {
|
||||
return deferredGlobalImportMetaExpressionType;
|
||||
}
|
||||
|
||||
function getGlobalESSymbolConstructorSymbol(reportErrors: boolean) {
|
||||
return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol" as __String, reportErrors));
|
||||
function getGlobalESSymbolConstructorSymbol(reportErrors: boolean): Symbol | undefined {
|
||||
return deferredGlobalESSymbolConstructorSymbol ||= getGlobalValueSymbol("Symbol" as __String, reportErrors);
|
||||
}
|
||||
|
||||
function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean) {
|
||||
return deferredGlobalESSymbolConstructorTypeSymbol || (deferredGlobalESSymbolConstructorTypeSymbol = getGlobalTypeSymbol("SymbolConstructor" as __String, reportErrors));
|
||||
function getGlobalESSymbolConstructorTypeSymbol(reportErrors: boolean): Symbol | undefined {
|
||||
return deferredGlobalESSymbolConstructorTypeSymbol ||= getGlobalTypeSymbol("SymbolConstructor" as __String, reportErrors);
|
||||
}
|
||||
|
||||
function getGlobalESSymbolType(reportErrors: boolean) {
|
||||
return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
return (deferredGlobalESSymbolType ||= getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
}
|
||||
|
||||
function getGlobalPromiseType(reportErrors: boolean) {
|
||||
return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalPromiseType ||= getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalPromiseLikeType(reportErrors: boolean) {
|
||||
return deferredGlobalPromiseLikeType || (deferredGlobalPromiseLikeType = getGlobalType("PromiseLike" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalPromiseLikeType ||= getGlobalType("PromiseLike" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalPromiseConstructorSymbol(reportErrors: boolean): Symbol | undefined {
|
||||
return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise" as __String, reportErrors));
|
||||
return deferredGlobalPromiseConstructorSymbol ||= getGlobalValueSymbol("Promise" as __String, reportErrors);
|
||||
}
|
||||
|
||||
function getGlobalPromiseConstructorLikeType(reportErrors: boolean) {
|
||||
return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
return (deferredGlobalPromiseConstructorLikeType ||= getGlobalType("PromiseConstructorLike" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
}
|
||||
|
||||
function getGlobalAsyncIterableType(reportErrors: boolean) {
|
||||
return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalAsyncIterableType ||= getGlobalType("AsyncIterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalAsyncIteratorType(reportErrors: boolean) {
|
||||
return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalAsyncIteratorType ||= getGlobalType("AsyncIterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalAsyncIterableIteratorType(reportErrors: boolean) {
|
||||
return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalAsyncIterableIteratorType ||= getGlobalType("AsyncIterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalAsyncGeneratorType(reportErrors: boolean) {
|
||||
return deferredGlobalAsyncGeneratorType || (deferredGlobalAsyncGeneratorType = getGlobalType("AsyncGenerator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalAsyncGeneratorType ||= getGlobalType("AsyncGenerator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalIterableType(reportErrors: boolean) {
|
||||
return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalIterableType ||= getGlobalType("Iterable" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalIteratorType(reportErrors: boolean) {
|
||||
return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalIteratorType ||= getGlobalType("Iterator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalIterableIteratorType(reportErrors: boolean) {
|
||||
return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalIterableIteratorType ||= getGlobalType("IterableIterator" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalGeneratorType(reportErrors: boolean) {
|
||||
return deferredGlobalGeneratorType || (deferredGlobalGeneratorType = getGlobalType("Generator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalGeneratorType ||= getGlobalType("Generator" as __String, /*arity*/ 3, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalIteratorYieldResultType(reportErrors: boolean) {
|
||||
return deferredGlobalIteratorYieldResultType || (deferredGlobalIteratorYieldResultType = getGlobalType("IteratorYieldResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalIteratorYieldResultType ||= getGlobalType("IteratorYieldResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalIteratorReturnResultType(reportErrors: boolean) {
|
||||
return deferredGlobalIteratorReturnResultType || (deferredGlobalIteratorReturnResultType = getGlobalType("IteratorReturnResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
return (deferredGlobalIteratorReturnResultType ||= getGlobalType("IteratorReturnResult" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalTypeOrUndefined(name: __String, arity = 0): ObjectType | undefined {
|
||||
@@ -13435,16 +13456,27 @@ namespace ts {
|
||||
return symbol && getTypeOfGlobalSymbol(symbol, arity) as GenericType;
|
||||
}
|
||||
|
||||
function getGlobalExtractSymbol(): Symbol {
|
||||
return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract" as __String, SymbolFlags.TypeAlias, Diagnostics.Cannot_find_global_type_0)!); // TODO: GH#18217
|
||||
function getGlobalExtractSymbol(): Symbol | undefined {
|
||||
// We always report an error, so cache a result in the event we could not resolve the symbol to prevent reporting it multiple times
|
||||
deferredGlobalExtractSymbol ||= getGlobalTypeAliasSymbol("Extract" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol;
|
||||
return deferredGlobalExtractSymbol === unknownSymbol ? undefined : deferredGlobalExtractSymbol;
|
||||
}
|
||||
|
||||
function getGlobalOmitSymbol(): Symbol {
|
||||
return deferredGlobalOmitSymbol || (deferredGlobalOmitSymbol = getGlobalSymbol("Omit" as __String, SymbolFlags.TypeAlias, Diagnostics.Cannot_find_global_type_0)!); // TODO: GH#18217
|
||||
function getGlobalOmitSymbol(): Symbol | undefined {
|
||||
// We always report an error, so cache a result in the event we could not resolve the symbol to prevent reporting it multiple times
|
||||
deferredGlobalOmitSymbol ||= getGlobalTypeAliasSymbol("Omit" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol;
|
||||
return deferredGlobalOmitSymbol === unknownSymbol ? undefined : deferredGlobalOmitSymbol;
|
||||
}
|
||||
|
||||
function getGlobalAwaitedSymbol(reportErrors: boolean): Symbol | undefined {
|
||||
if (reportErrors) debugger;
|
||||
// Only cache `unknownSymbol` if we are reporting errors so that we don't report the error more than once.
|
||||
deferredGlobalAwaitedSymbol ||= getGlobalTypeAliasSymbol("Awaited" as __String, /*arity*/ 1, reportErrors) || (reportErrors ? unknownSymbol : undefined);
|
||||
return deferredGlobalAwaitedSymbol === unknownSymbol ? undefined : deferredGlobalAwaitedSymbol;
|
||||
}
|
||||
|
||||
function getGlobalBigIntType(reportErrors: boolean) {
|
||||
return deferredGlobalBigIntType || (deferredGlobalBigIntType = getGlobalType("BigInt" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
return (deferredGlobalBigIntType ||= getGlobalType("BigInt" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25264,8 +25296,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (functionFlags & FunctionFlags.Async) { // Async function or AsyncGenerator function
|
||||
// Get the awaited type without the `Awaited<T>` alias
|
||||
const contextualAwaitedType = mapType(contextualReturnType, getAwaitedType);
|
||||
return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
|
||||
return contextualAwaitedType && getUnionType([unwrapAwaitedType(contextualAwaitedType), createPromiseLikeType(contextualAwaitedType)]);
|
||||
}
|
||||
|
||||
return contextualReturnType; // Regular function or Generator function
|
||||
@@ -25278,7 +25311,7 @@ namespace ts {
|
||||
const contextualType = getContextualType(node, contextFlags);
|
||||
if (contextualType) {
|
||||
const contextualAwaitedType = getAwaitedType(contextualType);
|
||||
return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
|
||||
return contextualAwaitedType && getUnionType([unwrapAwaitedType(contextualAwaitedType), createPromiseLikeType(contextualAwaitedType)]);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -32527,8 +32560,10 @@ namespace ts {
|
||||
let wouldWorkWithAwait = false;
|
||||
const errNode = errorNode || operatorToken;
|
||||
if (isRelated) {
|
||||
const awaitedLeftType = getAwaitedType(leftType);
|
||||
const awaitedRightType = getAwaitedType(rightType);
|
||||
let awaitedLeftType = getAwaitedType(leftType);
|
||||
let awaitedRightType = getAwaitedType(rightType);
|
||||
awaitedLeftType &&= unwrapAwaitedType(awaitedLeftType);
|
||||
awaitedRightType &&= unwrapAwaitedType(awaitedRightType);
|
||||
wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType)
|
||||
&& !!(awaitedLeftType && awaitedRightType)
|
||||
&& isRelated(awaitedLeftType, awaitedRightType);
|
||||
@@ -34561,6 +34596,11 @@ namespace ts {
|
||||
return typeAsPromise.promisedTypeOfPromise = getTypeArguments(type as GenericType)[0];
|
||||
}
|
||||
|
||||
// primitives with a `{ then() }` won't be unwrapped/adopted.
|
||||
if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const thenFunction = getTypeOfPropertyOfType(type, "then" as __String)!; // TODO: GH#18217
|
||||
if (isTypeAny(thenFunction)) {
|
||||
return undefined;
|
||||
@@ -34610,6 +34650,54 @@ namespace ts {
|
||||
return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull), SignatureKind.Call).length > 0;
|
||||
}
|
||||
|
||||
interface AwaitedTypeInstantiation extends Type {
|
||||
_awaitedTypeBrand: never;
|
||||
aliasSymbol: Symbol;
|
||||
aliasTypeArguments: readonly Type[];
|
||||
}
|
||||
|
||||
function isAwaitedTypeInstantiation(type: Type): type is AwaitedTypeInstantiation {
|
||||
if (type.flags & TypeFlags.Conditional) {
|
||||
const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ false);
|
||||
return !!awaitedSymbol && type.aliasSymbol === awaitedSymbol && type.aliasTypeArguments?.length === 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a generic `Awaited<T>`, gets `T`.
|
||||
*/
|
||||
function unwrapAwaitedType(type: Type) {
|
||||
return type.flags & TypeFlags.Union ? mapType(type, unwrapAwaitedType) :
|
||||
isAwaitedTypeInstantiation(type) ? type.aliasTypeArguments[0] :
|
||||
type;
|
||||
}
|
||||
|
||||
function createAwaitedTypeIfNeeded(type: Type): Type {
|
||||
if (isTypeAny(type)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
// If this is already an `Awaited<T>`, just return it. This helps to avoid `Awaited<Awaited<T>>` in higher-order.
|
||||
if (isAwaitedTypeInstantiation(type)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
// Only instantiate `Awaited<T>` if `T` contains possibly non-primitive types.
|
||||
if (isGenericObjectType(type) && !allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) {
|
||||
// Nothing to do if `Awaited<T>` doesn't exist
|
||||
const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ true);
|
||||
if (awaitedSymbol) {
|
||||
// Unwrap unions that may contain `Awaited<T>`, otherwise its possible to manufacture an `Awaited<Awaited<T> | U>` where
|
||||
// an `Awaited<T | U>` would suffice.
|
||||
return getTypeAliasInstantiation(awaitedSymbol, [unwrapAwaitedType(type)]);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.assert(getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like.");
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "awaited type" of a type.
|
||||
*
|
||||
@@ -34625,21 +34713,28 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
// If this is already an `Awaited<T>`, just return it. This avoids `Awaited<Awaited<T>>` in higher-order
|
||||
if (isAwaitedTypeInstantiation(type)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
// If we've already cached an awaited type, return a possible `Awaited<T>` for it.
|
||||
const typeAsAwaitable = type as PromiseOrAwaitableType;
|
||||
if (typeAsAwaitable.awaitedTypeOfType) {
|
||||
return typeAsAwaitable.awaitedTypeOfType;
|
||||
return createAwaitedTypeIfNeeded(typeAsAwaitable.awaitedTypeOfType);
|
||||
}
|
||||
|
||||
// For a union, get a union of the awaited types of each constituent.
|
||||
//
|
||||
return typeAsAwaitable.awaitedTypeOfType =
|
||||
mapType(type, errorNode ? constituentType => getAwaitedTypeWorker(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeWorker);
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const mapper = errorNode ? (constituentType: Type) => getAwaitedType(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedType;
|
||||
typeAsAwaitable.awaitedTypeOfType = mapType(type, mapper);
|
||||
return typeAsAwaitable.awaitedTypeOfType && createAwaitedTypeIfNeeded(typeAsAwaitable.awaitedTypeOfType);
|
||||
}
|
||||
|
||||
function getAwaitedTypeWorker(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined {
|
||||
const typeAsAwaitable = type as PromiseOrAwaitableType;
|
||||
if (typeAsAwaitable.awaitedTypeOfType) {
|
||||
return typeAsAwaitable.awaitedTypeOfType;
|
||||
// primitives with a `{ then() }` won't be unwrapped/adopted. This prevents `Awaited<T>` when `T extends string`
|
||||
// (or another primitive), since the `Awaited<T>` type only unwraps `object` types.
|
||||
if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
const promisedType = getPromisedTypeOfPromise(type);
|
||||
@@ -34694,7 +34789,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return typeAsAwaitable.awaitedTypeOfType = awaitedType;
|
||||
return createAwaitedTypeIfNeeded(typeAsAwaitable.awaitedTypeOfType = awaitedType);
|
||||
}
|
||||
|
||||
// The type was not a promise, so it could not be unwrapped any further.
|
||||
@@ -34714,13 +34809,13 @@ namespace ts {
|
||||
// be treated as a promise, they can cast to <any>.
|
||||
if (isThenableType(type)) {
|
||||
if (errorNode) {
|
||||
if (!diagnosticMessage) return Debug.fail();
|
||||
Debug.assertIsDefined(diagnosticMessage);
|
||||
error(errorNode, diagnosticMessage, arg0);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return typeAsAwaitable.awaitedTypeOfType = type;
|
||||
return createAwaitedTypeIfNeeded(typeAsAwaitable.awaitedTypeOfType = type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34770,7 +34865,7 @@ namespace ts {
|
||||
if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
|
||||
// The promise type was not a valid type reference to the global promise type, so we
|
||||
// report an error and return the unknown type.
|
||||
error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(getAwaitedType(returnType) || voidType));
|
||||
error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(unwrapAwaitedType(getAwaitedType(returnType) || voidType)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -36641,6 +36736,10 @@ namespace ts {
|
||||
if (iterationTypes === noIterationTypes) return noIterationTypes;
|
||||
if (iterationTypes === anyIterationTypes) return anyIterationTypes;
|
||||
const { yieldType, returnType, nextType } = iterationTypes;
|
||||
// if we're requesting diagnostics, report errors for a missing `Awaited<T>`.
|
||||
if (errorNode) {
|
||||
getGlobalAwaitedSymbol(/*reportErrors*/ true);
|
||||
}
|
||||
return createIterationTypes(
|
||||
getAwaitedType(yieldType, errorNode) || anyType,
|
||||
getAwaitedType(returnType, errorNode) || anyType,
|
||||
@@ -36667,7 +36766,9 @@ namespace ts {
|
||||
getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) ||
|
||||
getIterationTypesOfIterableFast(type, asyncIterationTypesResolver);
|
||||
if (iterationTypes) {
|
||||
return iterationTypes;
|
||||
return use & IterationUse.ForOfFlag ?
|
||||
getAsyncFromSyncIterationTypes(iterationTypes, errorNode) :
|
||||
iterationTypes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36756,7 +36857,7 @@ namespace ts {
|
||||
// While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
|
||||
// different definitions.
|
||||
const { returnType, nextType } = getIterationTypesOfGlobalIterableType(globalType, resolver);
|
||||
return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType));
|
||||
return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || yieldType, resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || returnType, nextType));
|
||||
}
|
||||
|
||||
// As an optimization, if the type is an instantiation of the following global type, then
|
||||
@@ -37097,7 +37198,7 @@ namespace ts {
|
||||
const isGenerator = !!(functionFlags & FunctionFlags.Generator);
|
||||
const isAsync = !!(functionFlags & FunctionFlags.Async);
|
||||
return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) ?? errorType :
|
||||
isAsync ? getAwaitedType(returnType) ?? errorType :
|
||||
isAsync ? unwrapAwaitedType(getAwaitedType(returnType) ?? errorType) :
|
||||
returnType;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+7
-5
@@ -1445,11 +1445,13 @@ interface Promise<T> {
|
||||
*/
|
||||
type Awaited<T> =
|
||||
T extends null | undefined ? T : // special case for `null | undefined` when not in `--noImplicitAny` mode
|
||||
T extends { then(onfulfilled: infer F): any } ? // thenable, extracts the first argument to `then()`
|
||||
F extends ((value: infer V) => any) ? // if the argument to `then` is callable, extracts the argument
|
||||
Awaited<V> : // recursively unwrap the value
|
||||
never : // the argument to `then` was not callable.
|
||||
T; // non-thenable
|
||||
T extends object ? // `await` only unwraps object types with a callable then. Non-object types are not unwrapped.
|
||||
T extends { then(onfulfilled: infer F): any } ? // thenable, extracts the first argument to `then()`
|
||||
F extends ((value: infer V) => any) ? // if the argument to `then` is callable, extracts the argument
|
||||
Awaited<V> : // recursively unwrap the value
|
||||
never : // the argument to `then` was not callable.
|
||||
T : // argument was not an object
|
||||
T; // non-thenable
|
||||
|
||||
interface ArrayLike<T> {
|
||||
readonly length: number;
|
||||
|
||||
@@ -6,9 +6,9 @@ class C {
|
||||
>method : () => void
|
||||
|
||||
var fn = async () => await this;
|
||||
>fn : () => Promise<this>
|
||||
>async () => await this : () => Promise<this>
|
||||
>await this : this
|
||||
>fn : () => Promise<Awaited<this>>
|
||||
>async () => await this : () => Promise<Awaited<this>>
|
||||
>await this : Awaited<this>
|
||||
>this : this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ class C {
|
||||
>method : () => void
|
||||
|
||||
var fn = async () => await this;
|
||||
>fn : () => Promise<this>
|
||||
>async () => await this : () => Promise<this>
|
||||
>await this : this
|
||||
>fn : () => Promise<Awaited<this>>
|
||||
>async () => await this : () => Promise<Awaited<this>>
|
||||
>await this : Awaited<this>
|
||||
>this : this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ class C {
|
||||
>method : () => void
|
||||
|
||||
var fn = async () => await this;
|
||||
>fn : () => Promise<this>
|
||||
>async () => await this : () => Promise<this>
|
||||
>await this : this
|
||||
>fn : () => Promise<Awaited<this>>
|
||||
>async () => await this : () => Promise<Awaited<this>>
|
||||
>await this : Awaited<this>
|
||||
>this : this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts(3,3): error TS2322: Type 'T | Yadda' is not assignable to type 'T'.
|
||||
'T' could be instantiated with an arbitrary type which could be unrelated to 'T | Yadda'.
|
||||
tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts(3,3): error TS2322: Type 'Yadda | Awaited<T>' is not assignable to type 'T'.
|
||||
'T' could be instantiated with an arbitrary type which could be unrelated to 'Yadda | Awaited<T>'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts (1 errors) ====
|
||||
@@ -7,8 +7,8 @@ tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts(3,3): error
|
||||
let yaddable = await getXOrYadda(x);
|
||||
return yaddable;
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'T | Yadda' is not assignable to type 'T'.
|
||||
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'T | Yadda'.
|
||||
!!! error TS2322: Type 'Yadda | Awaited<T>' is not assignable to type 'T'.
|
||||
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Yadda | Awaited<T>'.
|
||||
}
|
||||
|
||||
interface Yadda {
|
||||
|
||||
@@ -4,14 +4,14 @@ async function foo<T>(x: T): Promise<T> {
|
||||
>x : T
|
||||
|
||||
let yaddable = await getXOrYadda(x);
|
||||
>yaddable : T | Yadda
|
||||
>await getXOrYadda(x) : T | Yadda
|
||||
>yaddable : Yadda | Awaited<T>
|
||||
>await getXOrYadda(x) : Yadda | Awaited<T>
|
||||
>getXOrYadda(x) : T | Yadda
|
||||
>getXOrYadda : <T>(x: T) => T | Yadda
|
||||
>x : T
|
||||
|
||||
return yaddable;
|
||||
>yaddable : T | Yadda
|
||||
>yaddable : Yadda | Awaited<T>
|
||||
}
|
||||
|
||||
interface Yadda {
|
||||
|
||||
@@ -4,7 +4,7 @@ async function f<T>(source: Iterable<T> | AsyncIterable<T>) {
|
||||
>source : Iterable<T> | AsyncIterable<T>
|
||||
|
||||
for await (const x of source) {
|
||||
>x : T
|
||||
>x : Awaited<T>
|
||||
>source : Iterable<T> | AsyncIterable<T>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user