@@ -210,6 +210,11 @@ namespace ts {
210
210
getSuggestionForNonexistentProperty,
211
211
getSuggestionForNonexistentSymbol,
212
212
getBaseConstraintOfType,
213
+ getJsxNamespace,
214
+ resolveNameAtLocation(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined {
215
+ location = getParseTreeNode(location);
216
+ return resolveName(location, name, meaning, /*nameNotFoundMessage*/ undefined, name);
217
+ },
213
218
};
214
219
215
220
const tupleTypes: GenericType[] = [];
@@ -735,6 +740,7 @@ namespace ts {
735
740
if (declarationFile !== useFile) {
736
741
if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
737
742
(!compilerOptions.outFile && !compilerOptions.out) ||
743
+ isInTypeQuery(usage) ||
738
744
isInAmbientContext(declaration)) {
739
745
// nodes are in different files and order cannot be determined
740
746
return true;
@@ -847,7 +853,7 @@ namespace ts {
847
853
location: Node | undefined,
848
854
name: string,
849
855
meaning: SymbolFlags,
850
- nameNotFoundMessage: DiagnosticMessage,
856
+ nameNotFoundMessage: DiagnosticMessage | undefined ,
851
857
nameArg: string | Identifier,
852
858
suggestedNameNotFoundMessage?: DiagnosticMessage): Symbol {
853
859
return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, getSymbol, suggestedNameNotFoundMessage);
@@ -1364,6 +1370,9 @@ namespace ts {
1364
1370
// An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point'
1365
1371
// property with the type/namespace side interface 'Point'.
1366
1372
function combineValueAndTypeSymbols(valueSymbol: Symbol, typeSymbol: Symbol): Symbol {
1373
+ if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) {
1374
+ return unknownSymbol;
1375
+ }
1367
1376
if (valueSymbol.flags & (SymbolFlags.Type | SymbolFlags.Namespace)) {
1368
1377
return valueSymbol;
1369
1378
}
@@ -2282,7 +2291,7 @@ namespace ts {
2282
2291
2283
2292
function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string {
2284
2293
const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName);
2285
- Debug.assert(typeNode !== undefined, "should always get typenode? ");
2294
+ Debug.assert(typeNode !== undefined, "should always get typenode");
2286
2295
const options = { removeComments: true };
2287
2296
const writer = createTextWriter("");
2288
2297
const printer = createPrinter(options);
@@ -5841,7 +5850,8 @@ namespace ts {
5841
5850
}
5842
5851
}
5843
5852
return arrayFrom(props.values());
5844
- } else {
5853
+ }
5854
+ else {
5845
5855
return getPropertiesOfType(type);
5846
5856
}
5847
5857
}
@@ -8356,6 +8366,12 @@ namespace ts {
8356
8366
/**
8357
8367
* This is *not* a bi-directional relationship.
8358
8368
* If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
8369
+ *
8370
+ * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
8371
+ * It is used to check following cases:
8372
+ * - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
8373
+ * - the types of `case` clause expressions and their respective `switch` expressions.
8374
+ * - the type of an expression in a type assertion with the type being asserted.
8359
8375
*/
8360
8376
function isTypeComparableTo(source: Type, target: Type): boolean {
8361
8377
return isTypeRelatedTo(source, target, comparableRelation);
@@ -8583,6 +8599,7 @@ namespace ts {
8583
8599
8584
8600
function isEmptyObjectType(type: Type): boolean {
8585
8601
return type.flags & TypeFlags.Object ? isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type)) :
8602
+ type.flags & TypeFlags.NonPrimitive ? true :
8586
8603
type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isEmptyObjectType) :
8587
8604
type.flags & TypeFlags.Intersection ? !forEach((<UnionType>type).types, t => !isEmptyObjectType(t)) :
8588
8605
false;
@@ -14151,7 +14168,7 @@ namespace ts {
14151
14168
checkJsxPreconditions(node);
14152
14169
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
14153
14170
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
14154
- const reactRefErr = compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
14171
+ const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
14155
14172
const reactNamespace = getJsxNamespace();
14156
14173
const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace);
14157
14174
if (reactSym) {
@@ -14522,6 +14539,7 @@ namespace ts {
14522
14539
const maximumLengthDifference = Math.min(3, name.length * 0.34);
14523
14540
let bestDistance = Number.MAX_VALUE;
14524
14541
let bestCandidate = undefined;
14542
+ let justCheckExactMatches = false;
14525
14543
if (name.length > 30) {
14526
14544
return undefined;
14527
14545
}
@@ -14534,6 +14552,9 @@ namespace ts {
14534
14552
if (candidateName === name) {
14535
14553
return candidate;
14536
14554
}
14555
+ if (justCheckExactMatches) {
14556
+ continue;
14557
+ }
14537
14558
if (candidateName.length < 3 ||
14538
14559
name.length < 3 ||
14539
14560
candidateName === "eval" ||
@@ -14549,7 +14570,8 @@ namespace ts {
14549
14570
continue;
14550
14571
}
14551
14572
if (distance < 3) {
14552
- return candidate;
14573
+ justCheckExactMatches = true;
14574
+ bestCandidate = candidate;
14553
14575
}
14554
14576
else if (distance < bestDistance) {
14555
14577
bestDistance = distance;
@@ -16168,6 +16190,35 @@ namespace ts {
16168
16190
return getReturnTypeOfSignature(signature);
16169
16191
}
16170
16192
16193
+ function checkImportCallExpression(node: ImportCall): Type {
16194
+ // Check grammar of dynamic import
16195
+ checkGrammarArguments(node, node.arguments) || checkGrammarImportCallExpression(node);
16196
+
16197
+ if (node.arguments.length === 0) {
16198
+ return createPromiseReturnType(node, anyType);
16199
+ }
16200
+ const specifier = node.arguments[0];
16201
+ const specifierType = checkExpressionCached(specifier);
16202
+ // Even though multiple arugments is grammatically incorrect, type-check extra arguments for completion
16203
+ for (let i = 1; i < node.arguments.length; ++i) {
16204
+ checkExpressionCached(node.arguments[i]);
16205
+ }
16206
+
16207
+ if (specifierType.flags & TypeFlags.Undefined || specifierType.flags & TypeFlags.Null || !isTypeAssignableTo(specifierType, stringType)) {
16208
+ error(specifier, Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
16209
+ }
16210
+
16211
+ // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
16212
+ const moduleSymbol = resolveExternalModuleName(node, specifier);
16213
+ if (moduleSymbol) {
16214
+ const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true);
16215
+ if (esModuleSymbol) {
16216
+ return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol));
16217
+ }
16218
+ }
16219
+ return createPromiseReturnType(node, anyType);
16220
+ }
16221
+
16171
16222
function isCommonJsRequire(node: Node) {
16172
16223
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
16173
16224
return false;
@@ -16374,14 +16425,18 @@ namespace ts {
16374
16425
return emptyObjectType;
16375
16426
}
16376
16427
16377
- function createPromiseReturnType(func: FunctionLikeDeclaration, promisedType: Type) {
16428
+ function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall , promisedType: Type) {
16378
16429
const promiseType = createPromiseType(promisedType);
16379
16430
if (promiseType === emptyObjectType) {
16380
- error(func, Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
16431
+ error(func, isImportCall(func) ?
16432
+ Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
16433
+ Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
16381
16434
return unknownType;
16382
16435
}
16383
16436
else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
16384
- error(func, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
16437
+ error(func, isImportCall(func) ?
16438
+ Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
16439
+ Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
16385
16440
}
16386
16441
16387
16442
return promiseType;
@@ -17740,6 +17795,10 @@ namespace ts {
17740
17795
case SyntaxKind.ElementAccessExpression:
17741
17796
return checkIndexedAccess(<ElementAccessExpression>node);
17742
17797
case SyntaxKind.CallExpression:
17798
+ if ((<CallExpression>node).expression.kind === SyntaxKind.ImportKeyword) {
17799
+ return checkImportCallExpression(<ImportCall>node);
17800
+ }
17801
+ /* falls through */
17743
17802
case SyntaxKind.NewExpression:
17744
17803
return checkCallExpression(<CallExpression>node);
17745
17804
case SyntaxKind.TaggedTemplateExpression:
@@ -24665,6 +24724,27 @@ namespace ts {
24665
24724
});
24666
24725
return result;
24667
24726
}
24727
+
24728
+ function checkGrammarImportCallExpression(node: ImportCall): boolean {
24729
+ if (modulekind === ModuleKind.ES2015) {
24730
+ return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
24731
+ }
24732
+
24733
+ if (node.typeArguments) {
24734
+ return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_have_type_arguments);
24735
+ }
24736
+
24737
+ const arguments = node.arguments;
24738
+ if (arguments.length !== 1) {
24739
+ return grammarErrorOnNode(node, Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
24740
+ }
24741
+
24742
+ // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
24743
+ // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
24744
+ if (isSpreadElement(arguments[0])) {
24745
+ return grammarErrorOnNode(arguments[0], Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
24746
+ }
24747
+ }
24668
24748
}
24669
24749
24670
24750
/** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
0 commit comments