mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Revert to declared type when narrowing produces the nothing type
This commit is contained in:
+1
-18
@@ -696,23 +696,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function skipSimpleConditionalFlow(flow: FlowNode) {
|
||||
// We skip over simple conditional flows of the form 'x ? aaa : bbb', where 'aaa' and 'bbb' contain
|
||||
// no constructs that affect control flow type analysis. Such simple flows have no effect on the
|
||||
// code paths that follow and ignoring them means we'll do less work.
|
||||
if (flow.flags & FlowFlags.BranchLabel && (<FlowLabel>flow).antecedents.length === 2) {
|
||||
const a = (<FlowLabel>flow).antecedents[0];
|
||||
const b = (<FlowLabel>flow).antecedents[1];
|
||||
if ((a.flags & FlowFlags.TrueCondition && b.flags & FlowFlags.FalseCondition ||
|
||||
a.flags & FlowFlags.FalseCondition && b.flags & FlowFlags.TrueCondition) &&
|
||||
(<FlowCondition>a).antecedent === (<FlowCondition>b).antecedent &&
|
||||
(<FlowCondition>a).expression === (<FlowCondition>b).expression) {
|
||||
return (<FlowCondition>a).antecedent;
|
||||
}
|
||||
}
|
||||
return flow;
|
||||
}
|
||||
|
||||
function finishFlowLabel(flow: FlowLabel): FlowNode {
|
||||
const antecedents = flow.antecedents;
|
||||
if (!antecedents) {
|
||||
@@ -721,7 +704,7 @@ namespace ts {
|
||||
if (antecedents.length === 1) {
|
||||
return antecedents[0];
|
||||
}
|
||||
return skipSimpleConditionalFlow(flow);
|
||||
return flow;
|
||||
}
|
||||
|
||||
function isStatementCondition(node: Node) {
|
||||
|
||||
+16
-1
@@ -7702,7 +7702,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeAtFlowCondition(flow: FlowCondition) {
|
||||
return narrowType(getTypeAtFlowNode(flow.antecedent), flow.expression, (flow.flags & FlowFlags.TrueCondition) !== 0);
|
||||
let type = getTypeAtFlowNode(flow.antecedent);
|
||||
if (type !== emptyUnionType) {
|
||||
// If we have an antecedent type (meaning we're reachable in some way), we first
|
||||
// attempt to narrow the antecedent type. If that produces the nothing type, then
|
||||
// we take the type guard as an indication that control could reach here in a
|
||||
// manner not understood by the control flow analyzer (e.g. a function argument
|
||||
// has an invalid type, or a nested function has possibly made an assignment to a
|
||||
// captured variable). We proceed by reverting to the declared type and then
|
||||
// narrow that.
|
||||
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
|
||||
type = narrowType(type, flow.expression, assumeTrue);
|
||||
if (type === emptyUnionType) {
|
||||
type = narrowType(declaredType, flow.expression, assumeTrue);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getTypeAtFlowBranchLabel(flow: FlowLabel) {
|
||||
|
||||
Reference in New Issue
Block a user