@@ -46,6 +46,7 @@ namespace ts {
46
46
const compilerOptions = host.getCompilerOptions();
47
47
const languageVersion = compilerOptions.target || ScriptTarget.ES3;
48
48
const modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
49
+ const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System;
49
50
50
51
const emitResolver = createResolver();
51
52
@@ -532,7 +533,7 @@ namespace ts {
532
533
}
533
534
534
535
// Because of module/namespace merging, a module's exports are in scope,
535
- // yet we never want to treat an export specifier as putting a member in scope.
536
+ // yet we never want to treat an export specifier as putting a member in scope.
536
537
// Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
537
538
// Two things to note about this:
538
539
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
@@ -768,9 +769,12 @@ namespace ts {
768
769
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
769
770
if (moduleSymbol) {
770
771
const exportDefaultSymbol = resolveSymbol(moduleSymbol.exports["default"]);
771
- if (!exportDefaultSymbol) {
772
+ if (!exportDefaultSymbol && !allowSyntheticDefaultImports ) {
772
773
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
773
774
}
775
+ else if (!exportDefaultSymbol && allowSyntheticDefaultImports) {
776
+ return resolveSymbol(moduleSymbol.exports["export="]) || resolveSymbol(moduleSymbol);
777
+ }
774
778
return exportDefaultSymbol;
775
779
}
776
780
}
@@ -3197,7 +3201,7 @@ namespace ts {
3197
3201
case SyntaxKind.BooleanKeyword:
3198
3202
case SyntaxKind.SymbolKeyword:
3199
3203
case SyntaxKind.VoidKeyword:
3200
- case SyntaxKind.StringLiteral :
3204
+ case SyntaxKind.StringLiteralType :
3201
3205
return true;
3202
3206
case SyntaxKind.ArrayType:
3203
3207
return isIndependentType((<ArrayTypeNode>node).elementType);
@@ -3858,7 +3862,7 @@ namespace ts {
3858
3862
paramSymbol = resolvedSymbol;
3859
3863
}
3860
3864
parameters.push(paramSymbol);
3861
- if (param.type && param.type.kind === SyntaxKind.StringLiteral ) {
3865
+ if (param.type && param.type.kind === SyntaxKind.StringLiteralType ) {
3862
3866
hasStringLiterals = true;
3863
3867
}
3864
3868
@@ -4527,8 +4531,7 @@ namespace ts {
4527
4531
return links.resolvedType;
4528
4532
}
4529
4533
4530
- function getStringLiteralType(node: StringLiteral): StringLiteralType {
4531
- const text = node.text;
4534
+ function getStringLiteralTypeForText(text: string): StringLiteralType {
4532
4535
if (hasProperty(stringLiteralTypes, text)) {
4533
4536
return stringLiteralTypes[text];
4534
4537
}
@@ -4538,10 +4541,10 @@ namespace ts {
4538
4541
return type;
4539
4542
}
4540
4543
4541
- function getTypeFromStringLiteral (node: StringLiteral ): Type {
4544
+ function getTypeFromStringLiteralTypeNode (node: StringLiteralTypeNode ): Type {
4542
4545
const links = getNodeLinks(node);
4543
4546
if (!links.resolvedType) {
4544
- links.resolvedType = getStringLiteralType (node);
4547
+ links.resolvedType = getStringLiteralTypeForText (node.text );
4545
4548
}
4546
4549
return links.resolvedType;
4547
4550
}
@@ -4583,8 +4586,8 @@ namespace ts {
4583
4586
return voidType;
4584
4587
case SyntaxKind.ThisType:
4585
4588
return getTypeFromThisTypeNode(node);
4586
- case SyntaxKind.StringLiteral :
4587
- return getTypeFromStringLiteral(<StringLiteral >node);
4589
+ case SyntaxKind.StringLiteralType :
4590
+ return getTypeFromStringLiteralTypeNode(<StringLiteralTypeNode >node);
4588
4591
case SyntaxKind.TypeReference:
4589
4592
return getTypeFromTypeReference(<TypeReferenceNode>node);
4590
4593
case SyntaxKind.TypePredicate:
@@ -8791,7 +8794,7 @@ namespace ts {
8791
8794
// for the argument. In that case, we should check the argument.
8792
8795
if (argType === undefined) {
8793
8796
argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors
8794
- ? getStringLiteralType( <StringLiteral>arg)
8797
+ ? getStringLiteralTypeForText(( <StringLiteral>arg).text )
8795
8798
: checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
8796
8799
}
8797
8800
@@ -8986,7 +8989,7 @@ namespace ts {
8986
8989
case SyntaxKind.Identifier:
8987
8990
case SyntaxKind.NumericLiteral:
8988
8991
case SyntaxKind.StringLiteral:
8989
- return getStringLiteralType(<StringLiteral >element.name);
8992
+ return getStringLiteralTypeForText((<Identifier | LiteralExpression >element.name).text );
8990
8993
8991
8994
case SyntaxKind.ComputedPropertyName:
8992
8995
const nameType = checkComputedPropertyName(<ComputedPropertyName>element.name);
@@ -9855,17 +9858,25 @@ namespace ts {
9855
9858
return aggregatedTypes;
9856
9859
}
9857
9860
9858
- // TypeScript Specification 1.0 (6.3) - July 2014
9859
- // An explicitly typed function whose return type isn't the Void or the Any type
9860
- // must have at least one return statement somewhere in its body.
9861
- // An exception to this rule is if the function implementation consists of a single 'throw' statement.
9861
+ /*
9862
+ *TypeScript Specification 1.0 (6.3) - July 2014
9863
+ * An explicitly typed function whose return type isn't the Void or the Any type
9864
+ * must have at least one return statement somewhere in its body.
9865
+ * An exception to this rule is if the function implementation consists of a single 'throw' statement.
9866
+ * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
9867
+ */
9862
9868
function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: FunctionLikeDeclaration, returnType: Type): void {
9863
9869
if (!produceDiagnostics) {
9864
9870
return;
9865
9871
}
9866
9872
9867
- // Functions that return 'void' or 'any' don't need any return expressions.
9868
- if (returnType === voidType || isTypeAny(returnType)) {
9873
+ // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
9874
+ if (returnType && (returnType === voidType || isTypeAny(returnType))) {
9875
+ return;
9876
+ }
9877
+
9878
+ // if return type is not specified then we'll do the check only if 'noImplicitReturns' option is set
9879
+ if (!returnType && !compilerOptions.noImplicitReturns) {
9869
9880
return;
9870
9881
}
9871
9882
@@ -9875,13 +9886,14 @@ namespace ts {
9875
9886
return;
9876
9887
}
9877
9888
9878
- if (func.flags & NodeFlags.HasExplicitReturn) {
9889
+ if (!returnType || func.flags & NodeFlags.HasExplicitReturn) {
9879
9890
if (compilerOptions.noImplicitReturns) {
9880
- error(func.type, Diagnostics.Not_all_code_paths_return_a_value);
9891
+ error(func.type || func , Diagnostics.Not_all_code_paths_return_a_value);
9881
9892
}
9882
9893
}
9883
9894
else {
9884
9895
// This function does not conform to the specification.
9896
+ // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
9885
9897
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
9886
9898
}
9887
9899
}
@@ -9956,14 +9968,10 @@ namespace ts {
9956
9968
emitAwaiter = true;
9957
9969
}
9958
9970
9959
- const returnType = node.type && getTypeFromTypeNode(node.type);
9960
- let promisedType: Type;
9961
- if (returnType && isAsync) {
9962
- promisedType = checkAsyncFunctionReturnType(node);
9963
- }
9964
-
9965
- if (returnType && !node.asteriskToken) {
9966
- checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, isAsync ? promisedType : returnType);
9971
+ const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
9972
+ if (!node.asteriskToken) {
9973
+ // return is not necessary in the body of generators
9974
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
9967
9975
}
9968
9976
9969
9977
if (node.body) {
@@ -9986,13 +9994,13 @@ namespace ts {
9986
9994
// check assignability of the awaited type of the expression body against the promised type of
9987
9995
// its return type annotation.
9988
9996
const exprType = checkExpression(<Expression>node.body);
9989
- if (returnType ) {
9997
+ if (returnOrPromisedType ) {
9990
9998
if (isAsync) {
9991
9999
const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member);
9992
- checkTypeAssignableTo(awaitedType, promisedType , node.body);
10000
+ checkTypeAssignableTo(awaitedType, returnOrPromisedType , node.body);
9993
10001
}
9994
10002
else {
9995
- checkTypeAssignableTo(exprType, returnType , node.body);
10003
+ checkTypeAssignableTo(exprType, returnOrPromisedType , node.body);
9996
10004
}
9997
10005
}
9998
10006
@@ -10608,7 +10616,7 @@ namespace ts {
10608
10616
function checkStringLiteralExpression(node: StringLiteral): Type {
10609
10617
const contextualType = getContextualType(node);
10610
10618
if (contextualType && contextualTypeIsStringLiteralType(contextualType)) {
10611
- return getStringLiteralType (node);
10619
+ return getStringLiteralTypeForText (node.text );
10612
10620
}
10613
10621
10614
10622
return stringType;
@@ -11431,7 +11439,9 @@ namespace ts {
11431
11439
seen = c === node;
11432
11440
}
11433
11441
});
11434
- if (subsequentNode) {
11442
+ // We may be here because of some extra junk between overloads that could not be parsed into a valid node.
11443
+ // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
11444
+ if (subsequentNode && subsequentNode.pos === node.end) {
11435
11445
if (subsequentNode.kind === node.kind) {
11436
11446
const errorNode: Node = (<FunctionLikeDeclaration>subsequentNode).name || subsequentNode;
11437
11447
// TODO(jfreeman): These are methods, so handle computed name case
@@ -11442,7 +11452,7 @@ namespace ts {
11442
11452
// we can get here in two cases
11443
11453
// 1. mixed static and instance class members
11444
11454
// 2. something with the same name was defined before the set of overloads that prevents them from merging
11445
- // here we'll report error only for the first case since for second we should already report error in binder
11455
+ // here we'll report error only for the first case since for second we should already report error in binder
11446
11456
if (reportError) {
11447
11457
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
11448
11458
error(errorNode, diagnostic);
@@ -12132,14 +12142,9 @@ namespace ts {
12132
12142
}
12133
12143
12134
12144
checkSourceElement(node.body);
12135
- if (node.type && !isAccessor(node.kind) && !node.asteriskToken) {
12136
- const returnType = getTypeFromTypeNode(node.type);
12137
- let promisedType: Type;
12138
- if (isAsync) {
12139
- promisedType = checkAsyncFunctionReturnType(node);
12140
- }
12141
-
12142
- checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, isAsync ? promisedType : returnType);
12145
+ if (!isAccessor(node.kind) && !node.asteriskToken) {
12146
+ const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
12147
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
12143
12148
}
12144
12149
12145
12150
if (produceDiagnostics && !node.type) {
0 commit comments