mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 20:37:00 -05:00
Remove control flow-based undefined addition
Just add undefined when displaying the type. Don't actually add it to the type.
This commit is contained in:
@@ -822,15 +822,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function createFlowInitializedParameter(antecedent: FlowNode, node: ParameterDeclaration): FlowNode {
|
||||
setFlowNodeReferenced(antecedent);
|
||||
return <FlowInitializedParameter>{
|
||||
flags: FlowFlags.InitializedParameter,
|
||||
antecedent,
|
||||
node
|
||||
};
|
||||
}
|
||||
|
||||
function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode {
|
||||
setFlowNodeReferenced(antecedent);
|
||||
return <FlowArrayMutation>{
|
||||
@@ -2328,9 +2319,6 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
|
||||
if (node.initializer) {
|
||||
currentFlow = createFlowInitializedParameter(currentFlow, node);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a property-parameter, then also declare the property symbol into the
|
||||
|
||||
@@ -2694,7 +2694,11 @@ namespace ts {
|
||||
writePunctuation(writer, SyntaxKind.ColonToken);
|
||||
writeSpace(writer);
|
||||
|
||||
buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, symbolStack);
|
||||
let type = getTypeOfSymbol(p);
|
||||
if (strictNullChecks && parameterNode.initializer && !(getModifierFlags(parameterNode) & ModifierFlags.ParameterPropertyModifier)) {
|
||||
type = includeFalsyTypes(type, TypeFlags.Undefined);
|
||||
}
|
||||
buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
|
||||
}
|
||||
|
||||
function buildBindingPatternDisplay(bindingPattern: BindingPattern, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
@@ -3315,9 +3319,7 @@ namespace ts {
|
||||
|
||||
// Use type from type annotation if one is present
|
||||
if (declaration.type) {
|
||||
const isOptional = declaration.questionToken ||
|
||||
(declaration.initializer && declaration.kind === SyntaxKind.Parameter && !(getModifierFlags(declaration) & ModifierFlags.ParameterPropertyModifier));
|
||||
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ isOptional && includeOptionality);
|
||||
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) &&
|
||||
@@ -3368,10 +3370,7 @@ namespace ts {
|
||||
// Use the type of the initializer expression if one is present
|
||||
if (declaration.initializer) {
|
||||
const type = checkDeclarationInitializer(declaration);
|
||||
// initialized parameters (but not parameter properties) are optional
|
||||
const isOptional = declaration.questionToken ||
|
||||
(declaration.kind === SyntaxKind.Parameter && !(getModifierFlags(declaration) & ModifierFlags.ParameterPropertyModifier));
|
||||
return addOptionality(type, isOptional && includeOptionality);
|
||||
return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
|
||||
// If it is a short-hand property assignment, use the type of the identifier
|
||||
@@ -7101,8 +7100,8 @@ namespace ts {
|
||||
const sourceParams = source.parameters;
|
||||
const targetParams = target.parameters;
|
||||
for (let i = 0; i < checkCount; i++) {
|
||||
const s = i < sourceMax ? getTypeOfSymbol(sourceParams[i]) : getRestTypeOfSignature(source);
|
||||
const t = i < targetMax ? getTypeOfSymbol(targetParams[i]) : getRestTypeOfSignature(target);
|
||||
const s = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source);
|
||||
const t = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target);
|
||||
const related = compareTypes(s, t, /*reportErrors*/ false) || compareTypes(t, s, reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
@@ -8299,8 +8298,8 @@ namespace ts {
|
||||
|
||||
const targetLen = target.parameters.length;
|
||||
for (let i = 0; i < targetLen; i++) {
|
||||
const s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
|
||||
const t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]);
|
||||
const s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfParameter(source.parameters[i]);
|
||||
const t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfParameter(target.parameters[i]);
|
||||
const related = compareTypes(s, t);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
@@ -9196,8 +9195,8 @@ namespace ts {
|
||||
switch (source.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target) ||
|
||||
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement || target.kind === SyntaxKind.Parameter) &&
|
||||
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source as Identifier)) === getSymbolOfNode(target);
|
||||
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) &&
|
||||
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>source)) === getSymbolOfNode(target);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return target.kind === SyntaxKind.ThisKeyword;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
@@ -9291,13 +9290,6 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getInitializedParameterReducedType(declaredType: UnionType, assignedType: Type) {
|
||||
if (declaredType === assignedType || getFalsyFlags(assignedType) & TypeFlags.Undefined) {
|
||||
return declaredType;
|
||||
}
|
||||
return getTypeWithFacts(declaredType, TypeFacts.NEUndefined);
|
||||
}
|
||||
|
||||
// Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
|
||||
// For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
|
||||
// we remove type string.
|
||||
@@ -9478,7 +9470,7 @@ namespace ts {
|
||||
return links.resolvedType || getTypeOfExpression(node);
|
||||
}
|
||||
|
||||
function getInitialTypeOfVariableDeclaration(node: VariableDeclaration | ParameterDeclaration) {
|
||||
function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) {
|
||||
if (node.initializer) {
|
||||
return getTypeOfInitializer(node.initializer);
|
||||
}
|
||||
@@ -9491,15 +9483,15 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
function getInitialType(node: VariableDeclaration | BindingElement | ParameterDeclaration) {
|
||||
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.Parameter ?
|
||||
getInitialTypeOfVariableDeclaration(<VariableDeclaration | ParameterDeclaration>node) :
|
||||
function getInitialType(node: VariableDeclaration | BindingElement) {
|
||||
return node.kind === SyntaxKind.VariableDeclaration ?
|
||||
getInitialTypeOfVariableDeclaration(<VariableDeclaration>node) :
|
||||
getInitialTypeOfBindingElement(<BindingElement>node);
|
||||
}
|
||||
|
||||
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression | ParameterDeclaration) {
|
||||
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement || node.kind === SyntaxKind.Parameter ?
|
||||
getInitialType(<VariableDeclaration | BindingElement | ParameterDeclaration>node) :
|
||||
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) {
|
||||
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ?
|
||||
getInitialType(<VariableDeclaration | BindingElement>node) :
|
||||
getAssignedType(<Expression>node);
|
||||
}
|
||||
|
||||
@@ -9768,13 +9760,6 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (flow.flags & FlowFlags.InitializedParameter) {
|
||||
type = getTypeAtFlowInitializedParameter(flow as FlowInitializedParameter);
|
||||
if (!type) {
|
||||
flow = (flow as FlowInitializedParameter).antecedent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (flow.flags & FlowFlags.Condition) {
|
||||
type = getTypeAtFlowCondition(<FlowCondition>flow);
|
||||
}
|
||||
@@ -9822,20 +9807,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeAtFlowInitializedParameter(flow: FlowInitializedParameter) {
|
||||
const node = flow.node;
|
||||
// Parameter initializers don't really narrow the declared type except to remove undefined.
|
||||
// If the initializer includes undefined in the type, it doesn't even remove undefined.
|
||||
if (isMatchingReference(reference, node)) {
|
||||
if (declaredType.flags & TypeFlags.Union) {
|
||||
return getInitializedParameterReducedType(<UnionType>declaredType, getInitialOrAssignedType(node));
|
||||
}
|
||||
return declaredType;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getTypeAtFlowAssignment(flow: FlowAssignment) {
|
||||
const node = flow.node;
|
||||
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
|
||||
@@ -14033,10 +14004,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeOfParameter(symbol: Symbol) {
|
||||
const type = getTypeOfSymbol(symbol);
|
||||
if (strictNullChecks) {
|
||||
const declaration = symbol.valueDeclaration;
|
||||
if (declaration && (<VariableLikeDeclaration>declaration).initializer) {
|
||||
return includeFalsyTypes(type, TypeFlags.Undefined);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getTypeAtPosition(signature: Signature, pos: number): Type {
|
||||
return signature.hasRestParameter ?
|
||||
pos < signature.parameters.length - 1 ? getTypeOfSymbol(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
|
||||
pos < signature.parameters.length ? getTypeOfSymbol(signature.parameters[pos]) : anyType;
|
||||
pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
|
||||
pos < signature.parameters.length ? getTypeOfParameter(signature.parameters[pos]) : anyType;
|
||||
}
|
||||
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) {
|
||||
@@ -20652,9 +20634,15 @@ namespace ts {
|
||||
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
|
||||
// Get type of the symbol if this is the valid symbol otherwise get type at location
|
||||
const symbol = getSymbolOfNode(declaration);
|
||||
const type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
|
||||
let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
|
||||
? getWidenedLiteralType(getTypeOfSymbol(symbol))
|
||||
: unknownType;
|
||||
if (strictNullChecks &&
|
||||
declaration.kind === SyntaxKind.Parameter &&
|
||||
(declaration as ParameterDeclaration).initializer &&
|
||||
!(getModifierFlags(declaration) & ModifierFlags.ParameterPropertyModifier)) {
|
||||
type = includeFalsyTypes(type, TypeFlags.Undefined);
|
||||
}
|
||||
|
||||
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
|
||||
}
|
||||
|
||||
@@ -2062,13 +2062,12 @@
|
||||
BranchLabel = 1 << 2, // Non-looping junction
|
||||
LoopLabel = 1 << 3, // Looping junction
|
||||
Assignment = 1 << 4, // Assignment
|
||||
InitializedParameter = 1 << 5, // Parameter with initializer
|
||||
TrueCondition = 1 << 6, // Condition known to be true
|
||||
FalseCondition = 1 << 7, // Condition known to be false
|
||||
SwitchClause = 1 << 8, // Switch statement clause
|
||||
ArrayMutation = 1 << 9, // Potential array mutation
|
||||
Referenced = 1 << 10, // Referenced as antecedent once
|
||||
Shared = 1 << 11, // Referenced as antecedent more than once
|
||||
TrueCondition = 1 << 5, // Condition known to be true
|
||||
FalseCondition = 1 << 6, // Condition known to be false
|
||||
SwitchClause = 1 << 7, // Switch statement clause
|
||||
ArrayMutation = 1 << 8, // Potential array mutation
|
||||
Referenced = 1 << 9, // Referenced as antecedent once
|
||||
Shared = 1 << 10, // Referenced as antecedent more than once
|
||||
Label = BranchLabel | LoopLabel,
|
||||
Condition = TrueCondition | FalseCondition
|
||||
}
|
||||
@@ -2118,11 +2117,6 @@
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
export interface FlowInitializedParameter extends FlowNode {
|
||||
node: ParameterDeclaration;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
export type FlowType = Type | IncompleteType;
|
||||
|
||||
// Incomplete types occur during control flow analysis of loops. An IncompleteType
|
||||
|
||||
Reference in New Issue
Block a user