@@ -2690,7 +2690,11 @@ namespace ts {
2690
2690
writePunctuation(writer, SyntaxKind.ColonToken);
2691
2691
writeSpace(writer);
2692
2692
2693
- buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, symbolStack);
2693
+ let type = getTypeOfSymbol(p);
2694
+ if (isRequiredInitializedParameter(parameterNode)) {
2695
+ type = includeFalsyTypes(type, TypeFlags.Undefined);
2696
+ }
2697
+ buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
2694
2698
}
2695
2699
2696
2700
function buildBindingPatternDisplay(bindingPattern: BindingPattern, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
@@ -3271,6 +3275,16 @@ namespace ts {
3271
3275
return strictNullChecks && optional ? includeFalsyTypes(type, TypeFlags.Undefined) : type;
3272
3276
}
3273
3277
3278
+ /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
3279
+ function removeOptionalityFromAnnotation(annotatedType: Type, declaration: VariableLikeDeclaration): Type {
3280
+ const annotationIncludesUndefined = strictNullChecks &&
3281
+ declaration.kind === SyntaxKind.Parameter &&
3282
+ declaration.initializer &&
3283
+ getFalsyFlags(annotatedType) & TypeFlags.Undefined &&
3284
+ !(getFalsyFlags(checkExpression(declaration.initializer)) & TypeFlags.Undefined);
3285
+ return annotationIncludesUndefined ? getNonNullableType(annotatedType) : annotatedType;
3286
+ }
3287
+
3274
3288
// Return the inferred type for a variable, parameter, or property declaration
3275
3289
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, includeOptionality: boolean): Type {
3276
3290
if (declaration.flags & NodeFlags.JavaScriptFile) {
@@ -3304,7 +3318,8 @@ namespace ts {
3304
3318
3305
3319
// Use type from type annotation if one is present
3306
3320
if (declaration.type) {
3307
- return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
3321
+ const declaredType = removeOptionalityFromAnnotation(getTypeFromTypeNode(declaration.type), declaration);
3322
+ return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
3308
3323
}
3309
3324
3310
3325
if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
@@ -5198,6 +5213,12 @@ namespace ts {
5198
5213
Debug.assert(parameterIndex >= 0);
5199
5214
return parameterIndex >= signature.minArgumentCount;
5200
5215
}
5216
+ const iife = getImmediatelyInvokedFunctionExpression(node.parent);
5217
+ if (iife) {
5218
+ return !node.type &&
5219
+ !node.dotDotDotToken &&
5220
+ indexOf((node.parent as SignatureDeclaration).parameters, node) >= iife.arguments.length;
5221
+ }
5201
5222
5202
5223
return false;
5203
5224
}
@@ -7762,16 +7783,36 @@ namespace ts {
7762
7783
if (target.flags & TypeFlags.Union && containsType(targetTypes, source)) {
7763
7784
return Ternary.True;
7764
7785
}
7765
- const len = targetTypes.length;
7766
- for (let i = 0; i < len; i++) {
7767
- const related = isRelatedTo(source, targetTypes[i], reportErrors && i === len - 1);
7786
+ for (const type of targetTypes) {
7787
+ const related = isRelatedTo(source, type, /*reportErrors*/ false);
7768
7788
if (related) {
7769
7789
return related;
7770
7790
}
7771
7791
}
7792
+ if (reportErrors) {
7793
+ const discriminantType = findMatchingDiscriminantType(source, target);
7794
+ isRelatedTo(source, discriminantType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
7795
+ }
7772
7796
return Ternary.False;
7773
7797
}
7774
7798
7799
+ function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) {
7800
+ const sourceProperties = getPropertiesOfObjectType(source);
7801
+ if (sourceProperties) {
7802
+ for (const sourceProperty of sourceProperties) {
7803
+ if (isDiscriminantProperty(target, sourceProperty.name)) {
7804
+ const sourceType = getTypeOfSymbol(sourceProperty);
7805
+ for (const type of target.types) {
7806
+ const targetType = getTypeOfPropertyOfType(type, sourceProperty.name);
7807
+ if (targetType && isRelatedTo(sourceType, targetType)) {
7808
+ return type;
7809
+ }
7810
+ }
7811
+ }
7812
+ }
7813
+ }
7814
+ }
7815
+
7775
7816
function typeRelatedToEachType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
7776
7817
let result = Ternary.True;
7777
7818
const targetTypes = target.types;
@@ -8592,7 +8633,7 @@ namespace ts {
8592
8633
if (flags & TypeFlags.Void) types.push(voidType);
8593
8634
if (flags & TypeFlags.Undefined) types.push(undefinedType);
8594
8635
if (flags & TypeFlags.Null) types.push(nullType);
8595
- return getUnionType(types, /*subtypeReduction*/ true );
8636
+ return getUnionType(types);
8596
8637
}
8597
8638
8598
8639
function removeDefinitelyFalsyTypes(type: Type): Type {
@@ -9875,7 +9916,19 @@ namespace ts {
9875
9916
}
9876
9917
}
9877
9918
let type: FlowType;
9878
- if (flow.flags & FlowFlags.Assignment) {
9919
+ if (flow.flags & FlowFlags.AfterFinally) {
9920
+ // block flow edge: finally -> pre-try (for larger explanation check comment in binder.ts - bindTryStatement
9921
+ (<AfterFinallyFlow>flow).locked = true;
9922
+ type = getTypeAtFlowNode((<AfterFinallyFlow>flow).antecedent);
9923
+ (<AfterFinallyFlow>flow).locked = false;
9924
+ }
9925
+ else if (flow.flags & FlowFlags.PreFinally) {
9926
+ // locked pre-finally flows are filtered out in getTypeAtFlowBranchLabel
9927
+ // so here just redirect to antecedent
9928
+ flow = (<PreFinallyFlow>flow).antecedent;
9929
+ continue;
9930
+ }
9931
+ else if (flow.flags & FlowFlags.Assignment) {
9879
9932
type = getTypeAtFlowAssignment(<FlowAssignment>flow);
9880
9933
if (!type) {
9881
9934
flow = (<FlowAssignment>flow).antecedent;
@@ -10031,6 +10084,12 @@ namespace ts {
10031
10084
let subtypeReduction = false;
10032
10085
let seenIncomplete = false;
10033
10086
for (const antecedent of flow.antecedents) {
10087
+ if (antecedent.flags & FlowFlags.PreFinally && (<PreFinallyFlow>antecedent).lock.locked) {
10088
+ // if flow correspond to branch from pre-try to finally and this branch is locked - this means that
10089
+ // we initially have started following the flow outside the finally block.
10090
+ // in this case we should ignore this branch.
10091
+ continue;
10092
+ }
10034
10093
const flowType = getTypeAtFlowNode(antecedent);
10035
10094
const type = getTypeFromFlowType(flowType);
10036
10095
// If the type at a particular antecedent path is the declared type and the
@@ -20710,6 +20769,13 @@ namespace ts {
20710
20769
return false;
20711
20770
}
20712
20771
20772
+ function isRequiredInitializedParameter(parameter: ParameterDeclaration) {
20773
+ return strictNullChecks &&
20774
+ !isOptionalParameter(parameter) &&
20775
+ parameter.initializer &&
20776
+ !(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier);
20777
+ }
20778
+
20713
20779
function getNodeCheckFlags(node: Node): NodeCheckFlags {
20714
20780
node = getParseTreeNode(node);
20715
20781
return node ? getNodeLinks(node).flags : undefined;
@@ -20801,10 +20867,12 @@ namespace ts {
20801
20867
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
20802
20868
// Get type of the symbol if this is the valid symbol otherwise get type at location
20803
20869
const symbol = getSymbolOfNode(declaration);
20804
- const type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
20870
+ let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
20805
20871
? getWidenedLiteralType(getTypeOfSymbol(symbol))
20806
20872
: unknownType;
20807
-
20873
+ if (flags & TypeFormatFlags.AddUndefined) {
20874
+ type = includeFalsyTypes(type, TypeFlags.Undefined);
20875
+ }
20808
20876
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
20809
20877
}
20810
20878
@@ -20903,6 +20971,7 @@ namespace ts {
20903
20971
isTopLevelValueImportEqualsWithEntityName,
20904
20972
isDeclarationVisible,
20905
20973
isImplementationOfOverload,
20974
+ isRequiredInitializedParameter,
20906
20975
writeTypeOfDeclaration,
20907
20976
writeReturnTypeOfSignatureDeclaration,
20908
20977
writeTypeOfExpression,
0 commit comments