@@ -5787,90 +5787,6 @@ namespace ts {
5787
5787
}
5788
5788
}
5789
5789
5790
- function getStaticTypeFromTypeNode(node: TypeNode) {
5791
- switch (node.kind) {
5792
- case SyntaxKind.AnyKeyword:
5793
- case SyntaxKind.JSDocAllType:
5794
- case SyntaxKind.JSDocUnknownType:
5795
- return anyType;
5796
- case SyntaxKind.StringKeyword:
5797
- return stringType;
5798
- case SyntaxKind.NumberKeyword:
5799
- return numberType;
5800
- case SyntaxKind.BooleanKeyword:
5801
- return booleanType;
5802
- case SyntaxKind.SymbolKeyword:
5803
- return esSymbolType;
5804
- case SyntaxKind.VoidKeyword:
5805
- return voidType;
5806
- case SyntaxKind.UndefinedKeyword:
5807
- return undefinedType;
5808
- case SyntaxKind.NullKeyword:
5809
- return nullType;
5810
- case SyntaxKind.NeverKeyword:
5811
- return neverType;
5812
- case SyntaxKind.JSDocNullKeyword:
5813
- return nullType;
5814
- case SyntaxKind.JSDocUndefinedKeyword:
5815
- return undefinedType;
5816
- case SyntaxKind.JSDocNeverKeyword:
5817
- return neverType;
5818
- case SyntaxKind.ThisType:
5819
- case SyntaxKind.ThisKeyword:
5820
- return getTypeFromThisTypeNode(node);
5821
- case SyntaxKind.LiteralType:
5822
- return getTypeFromLiteralTypeNode(<LiteralTypeNode>node);
5823
- case SyntaxKind.JSDocLiteralType:
5824
- return getTypeFromLiteralTypeNode((<JSDocLiteralType>node).literal);
5825
- case SyntaxKind.TypeReference:
5826
- case SyntaxKind.JSDocTypeReference:
5827
- return getTypeFromTypeReference(<TypeReferenceNode>node);
5828
- case SyntaxKind.TypePredicate:
5829
- return booleanType;
5830
- case SyntaxKind.ExpressionWithTypeArguments:
5831
- return getTypeFromTypeReference(<ExpressionWithTypeArguments>node);
5832
- case SyntaxKind.TypeQuery:
5833
- return getTypeFromTypeQueryNode(<TypeQueryNode>node);
5834
- case SyntaxKind.ArrayType:
5835
- case SyntaxKind.JSDocArrayType:
5836
- return getTypeFromArrayTypeNode(<ArrayTypeNode>node);
5837
- case SyntaxKind.TupleType:
5838
- return getTypeFromTupleTypeNode(<TupleTypeNode>node);
5839
- case SyntaxKind.UnionType:
5840
- case SyntaxKind.JSDocUnionType:
5841
- return getTypeFromUnionTypeNode(<UnionTypeNode>node, aliasSymbol, aliasTypeArguments);
5842
- case SyntaxKind.IntersectionType:
5843
- return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node, aliasSymbol, aliasTypeArguments);
5844
- case SyntaxKind.ParenthesizedType:
5845
- case SyntaxKind.JSDocNullableType:
5846
- case SyntaxKind.JSDocNonNullableType:
5847
- case SyntaxKind.JSDocConstructorType:
5848
- case SyntaxKind.JSDocThisType:
5849
- case SyntaxKind.JSDocOptionalType:
5850
- return getTypeFromTypeNode((<ParenthesizedTypeNode | JSDocTypeReferencingNode>node).type);
5851
- case SyntaxKind.JSDocRecordType:
5852
- return getTypeFromTypeNode((node as JSDocRecordType).literal);
5853
- case SyntaxKind.FunctionType:
5854
- case SyntaxKind.ConstructorType:
5855
- case SyntaxKind.TypeLiteral:
5856
- case SyntaxKind.JSDocTypeLiteral:
5857
- case SyntaxKind.JSDocFunctionType:
5858
- return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node, aliasSymbol, aliasTypeArguments);
5859
- // This function assumes that an identifier or qualified name is a type expression
5860
- // Callers should first ensure this by calling isTypeNode
5861
- case SyntaxKind.Identifier:
5862
- case SyntaxKind.QualifiedName:
5863
- const symbol = getSymbolAtLocation(node);
5864
- return symbol && getDeclaredTypeOfSymbol(symbol);
5865
- case SyntaxKind.JSDocTupleType:
5866
- return getTypeFromJSDocTupleType(<JSDocTupleType>node);
5867
- case SyntaxKind.JSDocVariadicType:
5868
- return getTypeFromJSDocVariadicType(<JSDocVariadicType>node);
5869
- default:
5870
- return unknownType;
5871
- }
5872
- }
5873
-
5874
5790
function instantiateList<T>(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] {
5875
5791
if (items && items.length) {
5876
5792
const result: T[] = [];
@@ -15308,56 +15224,55 @@ namespace ts {
15308
15224
// }
15309
15225
//
15310
15226
15311
- const promiseName = getEntityNameFromTypeNode(node.type);
15312
- const rootName = getFirstIdentifier(promiseName);
15313
-
15314
- // Mark the root symbol as referenced.
15315
- getSymbolLinks(rootName.symbol).referenced = true;
15227
+ // Always mark the type node as referenced if it points to a value
15228
+ markTypeNodeAsReferenced(node.type);
15316
15229
15230
+ const promiseConstructorName = getEntityNameFromTypeNode(node.type);
15317
15231
const promiseType = getTypeFromTypeNode(node.type);
15318
- if (promiseType === unknownType && compilerOptions.isolatedModules) {
15319
- // If we are compiling with isolatedModules, we may not be able to resolve the
15320
- // type as a value. As such, we will just return unknownType.
15232
+ if (promiseType === unknownType) {
15233
+ if (!compilerOptions.isolatedModules) {
15234
+ if (promiseConstructorName) {
15235
+ error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
15236
+ }
15237
+ else {
15238
+ error(node.type, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
15239
+ }
15240
+ }
15241
+ return unknownType;
15242
+ }
15243
+
15244
+ if (promiseConstructorName === undefined) {
15245
+ error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(promiseType));
15321
15246
return unknownType;
15322
15247
}
15323
15248
15324
- const promiseConstructorType = getStaticTypeFromTypeNode(node.type);
15249
+ const promiseConstructorSymbol = resolveEntityName(promiseConstructorName, SymbolFlags.Value, /*ignoreErrors*/ true);
15250
+ const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType;
15251
+ if (promiseConstructorType === unknownType) {
15252
+ error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
15253
+ return unknownType;
15254
+ }
15325
15255
15326
15256
const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
15327
15257
if (globalPromiseConstructorLikeType === emptyObjectType) {
15328
15258
// If we couldn't resolve the global PromiseConstructorLike type we cannot verify
15329
15259
// compatibility with __awaiter.
15330
- error(node.type || node.name || node , Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type );
15260
+ error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName) );
15331
15261
return unknownType;
15332
15262
}
15333
15263
15334
- // When we get the type of the `Promise` symbol here, we get the type of the static
15335
- // side of the `Promise` class, which would be `{ new <T>(...): Promise<T> }`.
15336
-
15337
- const promiseConstructor = getNodeLinks(node.type).resolvedSymbol;
15338
- if (!promiseConstructor) {
15339
- // try to fall back to global promise type.
15340
- const typeName = promiseConstructor
15341
- ? symbolToString(promiseConstructor)
15342
- : typeToString(promiseType);
15343
- return checkCorrectPromiseType(promiseType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName);
15344
- }
15345
-
15346
- // If the Promise constructor, resolved locally, is an alias symbol we should mark it as referenced.
15347
- checkReturnTypeAnnotationAsExpression(node);
15348
-
15349
- // Validate the promise constructor type.
15350
- const promiseConstructorType = getTypeOfSymbol(promiseConstructor);
15351
- if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
15264
+ if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type,
15265
+ Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
15352
15266
return unknownType;
15353
15267
}
15354
15268
15355
15269
// Verify there is no local declaration that could collide with the promise constructor.
15356
- const rootSymbol = getSymbol(node.locals, rootName.text, SymbolFlags.Value);
15357
- if (rootSymbol) {
15358
- error(rootSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
15270
+ const rootName = promiseConstructorName && getFirstIdentifier(promiseConstructorName);
15271
+ const collidingSymbol = getSymbol(node.locals, rootName.text, SymbolFlags.Value);
15272
+ if (collidingSymbol) {
15273
+ error(collidingSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
15359
15274
rootName.text,
15360
- getFullyQualifiedName(promiseConstructor ));
15275
+ entityNameToString(promiseConstructorName ));
15361
15276
return unknownType;
15362
15277
}
15363
15278
@@ -15415,44 +15330,19 @@ namespace ts {
15415
15330
errorInfo);
15416
15331
}
15417
15332
15418
- /** Checks a type reference node as an expression. */
15419
- function checkTypeNodeAsExpression(node: TypeNode) {
15420
- // When we are emitting type metadata for decorators, we need to try to check the type
15421
- // as if it were an expression so that we can emit the type in a value position when we
15422
- // serialize the type metadata.
15423
- if (node && node.kind === SyntaxKind.TypeReference) {
15424
- const root = getFirstIdentifier((<TypeReferenceNode>node).typeName);
15425
- const meaning = root.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace;
15426
- // Resolve type so we know which symbol is referenced
15427
- const rootSymbol = resolveName(root, root.text, meaning | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
15428
- // Resolved symbol is alias
15429
- if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias) {
15430
- const aliasTarget = resolveAlias(rootSymbol);
15431
- // If alias has value symbol - mark alias as referenced
15432
- if (aliasTarget.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
15433
- markAliasSymbolAsReferenced(rootSymbol);
15434
- }
15435
- }
15436
- }
15437
- }
15438
-
15439
15333
/**
15440
- * Checks the type annotation of an accessor declaration or property declaration as
15441
- * an expression if it is a type reference to a type with a value declaration.
15442
- */
15443
- function checkTypeAnnotationAsExpression(node: VariableLikeDeclaration) {
15444
- checkTypeNodeAsExpression((<PropertyDeclaration>node).type);
15445
- }
15446
-
15447
- function checkReturnTypeAnnotationAsExpression(node: FunctionLikeDeclaration) {
15448
- checkTypeNodeAsExpression(node.type);
15449
- }
15450
-
15451
- /** Checks the type annotation of the parameters of a function/method or the constructor of a class as expressions */
15452
- function checkParameterTypeAnnotationsAsExpressions(node: FunctionLikeDeclaration) {
15453
- // ensure all type annotations with a value declaration are checked as an expression
15454
- for (const parameter of node.parameters) {
15455
- checkTypeAnnotationAsExpression(parameter);
15334
+ * If a TypeNode can be resolved to a value symbol imported from an external module, it is
15335
+ * marked as referenced to prevent import elision.
15336
+ */
15337
+ function markTypeNodeAsReferenced(node: TypeNode) {
15338
+ const typeName = node && getEntityNameFromTypeNode(node);
15339
+ const rootName = typeName && getFirstIdentifier(typeName);
15340
+ const rootSymbol = rootName && resolveName(rootName, rootName.text, (typeName.kind === SyntaxKind.Identifier ? SymbolFlags.Type : SymbolFlags.Namespace) | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
15341
+ if (rootSymbol
15342
+ && rootSymbol.flags & SymbolFlags.Alias
15343
+ && symbolIsValue(rootSymbol)
15344
+ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
15345
+ markAliasSymbolAsReferenced(rootSymbol);
15456
15346
}
15457
15347
}
15458
15348
@@ -15478,20 +15368,25 @@ namespace ts {
15478
15368
case SyntaxKind.ClassDeclaration:
15479
15369
const constructor = getFirstConstructorWithBody(<ClassDeclaration>node);
15480
15370
if (constructor) {
15481
- checkParameterTypeAnnotationsAsExpressions(constructor);
15371
+ for (const parameter of constructor.parameters) {
15372
+ markTypeNodeAsReferenced(parameter.type);
15373
+ }
15482
15374
}
15483
15375
break;
15484
15376
15485
15377
case SyntaxKind.MethodDeclaration:
15486
15378
case SyntaxKind.GetAccessor:
15487
15379
case SyntaxKind.SetAccessor:
15488
- checkParameterTypeAnnotationsAsExpressions(<FunctionLikeDeclaration>node);
15489
- checkReturnTypeAnnotationAsExpression(<FunctionLikeDeclaration>node);
15380
+ for (const parameter of (<FunctionLikeDeclaration>node).parameters) {
15381
+ markTypeNodeAsReferenced(parameter.type);
15382
+ }
15383
+
15384
+ markTypeNodeAsReferenced((<FunctionLikeDeclaration>node).type);
15490
15385
break;
15491
15386
15492
15387
case SyntaxKind.PropertyDeclaration:
15493
15388
case SyntaxKind.Parameter:
15494
- checkTypeAnnotationAsExpression( <PropertyDeclaration | ParameterDeclaration>node);
15389
+ markTypeNodeAsReferenced(( <PropertyDeclaration | ParameterDeclaration>node).type );
15495
15390
break;
15496
15391
}
15497
15392
}
0 commit comments