@@ -9060,8 +9060,8 @@ namespace ts {
9060
9060
switch (source.kind) {
9061
9061
case SyntaxKind.Identifier:
9062
9062
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target) ||
9063
- (target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) && getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>source)) === getSymbolOfNode(target) ||
9064
- target.kind === SyntaxKind.Parameter && getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target);
9063
+ (target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement || target.kind === SyntaxKind.Parameter) &&
9064
+ getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target);
9065
9065
case SyntaxKind.ThisKeyword:
9066
9066
return target.kind === SyntaxKind.ThisKeyword;
9067
9067
case SyntaxKind.PropertyAccessExpression:
@@ -9155,6 +9155,13 @@ namespace ts {
9155
9155
return false;
9156
9156
}
9157
9157
9158
+ function getInitializedParameterReducedType(declaredType: UnionType, assignedType: Type) {
9159
+ if (declaredType === assignedType || getFalsyFlags(assignedType) & TypeFlags.Undefined) {
9160
+ return declaredType;
9161
+ }
9162
+ return getTypeWithFacts(declaredType, TypeFacts.NEUndefined);
9163
+ }
9164
+
9158
9165
// Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
9159
9166
// For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
9160
9167
// we remove type string.
@@ -9351,7 +9358,7 @@ namespace ts {
9351
9358
getInitialTypeOfBindingElement(<BindingElement>node);
9352
9359
}
9353
9360
9354
- function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) {
9361
+ function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression | ParameterDeclaration ) {
9355
9362
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement || node.kind === SyntaxKind.Parameter ?
9356
9363
getInitialType(<VariableDeclaration | BindingElement | ParameterDeclaration>node) :
9357
9364
getAssignedType(<Expression>node);
@@ -9622,6 +9629,13 @@ namespace ts {
9622
9629
continue;
9623
9630
}
9624
9631
}
9632
+ else if (flow.flags & FlowFlags.InitializedParameter) {
9633
+ type = getTypeAtFlowInitializedParameter(flow as FlowInitializedParameter);
9634
+ if (!type) {
9635
+ flow = (flow as FlowInitializedParameter).antecedent;
9636
+ continue;
9637
+ }
9638
+ }
9625
9639
else if (flow.flags & FlowFlags.Condition) {
9626
9640
type = getTypeAtFlowCondition(<FlowCondition>flow);
9627
9641
}
@@ -9669,6 +9683,20 @@ namespace ts {
9669
9683
}
9670
9684
}
9671
9685
9686
+ function getTypeAtFlowInitializedParameter(flow: FlowInitializedParameter) {
9687
+ const node = flow.node;
9688
+ // Parameter initializers don't really narrow the declared type except to remove undefined.
9689
+ // If the initializer includes undefined in the type, it doesn't even remove undefined.
9690
+ if (isMatchingReference(reference, node)) {
9691
+ if (declaredType.flags & TypeFlags.Union) {
9692
+ return getInitializedParameterReducedType(<UnionType>declaredType, getInitialOrAssignedType(node));
9693
+ }
9694
+ return declaredType;
9695
+ }
9696
+
9697
+ return undefined;
9698
+ }
9699
+
9672
9700
function getTypeAtFlowAssignment(flow: FlowAssignment) {
9673
9701
const node = flow.node;
9674
9702
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
0 commit comments