Skip to content

Commit 6f7c984

Browse files
committed
Address PR comments
1. Add undefined only when an initialized parameter is required (not optional). 2. Create isRequiredInitializedParameter helper function 3. Call this function only once from declarationEmitter
1 parent 7cf595a commit 6f7c984

File tree

3 files changed

+25
-21
lines changed

3 files changed

+25
-21
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,7 +2695,7 @@ namespace ts {
26952695
writeSpace(writer);
26962696

26972697
let type = getTypeOfSymbol(p);
2698-
if (strictNullChecks && parameterNode.initializer && !(getModifierFlags(parameterNode) & ModifierFlags.ParameterPropertyModifier)) {
2698+
if (isRequiredInitializedParameter(parameterNode)) {
26992699
type = includeFalsyTypes(type, TypeFlags.Undefined);
27002700
}
27012701
buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack);
@@ -3182,12 +3182,6 @@ namespace ts {
31823182
}
31833183
return parentType;
31843184
}
3185-
// In strict null checking mode, a default value of a binding pattern adds undefined,
3186-
// which should be removed to get the type of the elements
3187-
const func = getContainingFunction(declaration);
3188-
if (strictNullChecks && func && !func.body && getFalsyFlags(parentType) & TypeFlags.Undefined) {
3189-
parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined);
3190-
}
31913185

31923186
let type: Type;
31933187
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
@@ -20554,6 +20548,13 @@ namespace ts {
2055420548
return false;
2055520549
}
2055620550

20551+
function isRequiredInitializedParameter(parameter: ParameterDeclaration) {
20552+
return strictNullChecks &&
20553+
!isOptionalParameter(parameter) &&
20554+
parameter.initializer &&
20555+
!(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier);
20556+
}
20557+
2055720558
function getNodeCheckFlags(node: Node): NodeCheckFlags {
2055820559
node = getParseTreeNode(node);
2055920560
return node ? getNodeLinks(node).flags : undefined;
@@ -20648,13 +20649,9 @@ namespace ts {
2064820649
let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature))
2064920650
? getWidenedLiteralType(getTypeOfSymbol(symbol))
2065020651
: unknownType;
20651-
if (strictNullChecks &&
20652-
declaration.kind === SyntaxKind.Parameter &&
20653-
(declaration as ParameterDeclaration).initializer &&
20654-
!(getModifierFlags(declaration) & ModifierFlags.ParameterPropertyModifier)) {
20652+
if (flags & TypeFormatFlags.AddUndefined) {
2065520653
type = includeFalsyTypes(type, TypeFlags.Undefined);
2065620654
}
20657-
2065820655
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
2065920656
}
2066020657

@@ -20753,6 +20750,7 @@ namespace ts {
2075320750
isTopLevelValueImportEqualsWithEntityName,
2075420751
isDeclarationVisible,
2075520752
isImplementationOfOverload,
20753+
isRequiredInitializedParameter,
2075620754
writeTypeOfDeclaration,
2075720755
writeReturnTypeOfSignatureDeclaration,
2075820756
writeTypeOfExpression,

src/compiler/declarationEmitter.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,22 @@ namespace ts {
322322
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
323323
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
324324
write(": ");
325-
if (type) {
325+
326+
// use the checker's type, not the declared type,
327+
// for non-optional initialized parameters that aren't a parameter property
328+
const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter &&
329+
resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration);
330+
if (type && !shouldUseResolverType) {
326331
// Write the type
327332
emitType(type);
328333
}
329334
else {
330335
errorNameNode = declaration.name;
331-
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
336+
let format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue;
337+
if (shouldUseResolverType) {
338+
format |= TypeFormatFlags.AddUndefined;
339+
}
340+
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
332341
errorNameNode = undefined;
333342
}
334343
}
@@ -1594,12 +1603,7 @@ namespace ts {
15941603
emitTypeOfVariableDeclarationFromTypeLiteral(node);
15951604
}
15961605
else if (!hasModifier(node.parent, ModifierFlags.Private)) {
1597-
// use the checker's type, not the declared type,
1598-
// for optional parameters and initialized ones that aren't a parameter property
1599-
const typeShouldAddUndefined = resolver.isOptionalParameter(node) ||
1600-
node.initializer && !(getModifierFlags(node) & ModifierFlags.ParameterPropertyModifier);
1601-
const typeNode = typeShouldAddUndefined ? undefined : node.type;
1602-
writeTypeOfDeclaration(node, typeNode, getParameterDeclarationTypeVisibilityError);
1606+
writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError);
16031607
}
16041608

16051609
function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {

src/compiler/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2466,7 +2466,8 @@
24662466
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
24672467
InTypeAlias = 0x00000200, // Writing type in type alias declaration
24682468
UseTypeAliasValue = 0x00000400, // Serialize the type instead of using type-alias. This is needed when we emit declaration file.
2469-
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
2469+
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
2470+
AddUndefined = 0x00001000, // Add undefined to types of initialized, non-optional parameters
24702471
}
24712472

24722473
export const enum SymbolFormatFlags {
@@ -2571,6 +2572,7 @@
25712572
isDeclarationVisible(node: Declaration): boolean;
25722573
collectLinkedAliases(node: Identifier): Node[];
25732574
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
2575+
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
25742576
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
25752577
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
25762578
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;

0 commit comments

Comments
 (0)