Skip to content

Commit 9f69cd5

Browse files
authored
Merge pull request #16497 from Microsoft/use-checker-for-decl-emit-of-optional-param-props
Use checker for declaration emit of optional, uninitialised parameter properties
2 parents 31f0814 + 5780494 commit 9f69cd5

File tree

8 files changed

+64
-4
lines changed

8 files changed

+64
-4
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23008,6 +23008,13 @@ namespace ts {
2300823008
!(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier);
2300923009
}
2301023010

23011+
function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) {
23012+
return strictNullChecks &&
23013+
isOptionalParameter(parameter) &&
23014+
!parameter.initializer &&
23015+
!!(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier);
23016+
}
23017+
2301123018
function getNodeCheckFlags(node: Node): NodeCheckFlags {
2301223019
return getNodeLinks(node).flags;
2301323020
}
@@ -23217,6 +23224,7 @@ namespace ts {
2321723224
isDeclarationVisible,
2321823225
isImplementationOfOverload,
2321923226
isRequiredInitializedParameter,
23227+
isOptionalUninitializedParameterProperty,
2322023228
writeTypeOfDeclaration,
2322123229
writeReturnTypeOfSignatureDeclaration,
2322223230
writeTypeOfExpression,

src/compiler/declarationEmitter.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,12 @@ namespace ts {
335335
write(": ");
336336

337337
// use the checker's type, not the declared type,
338-
// for non-optional initialized parameters that aren't a parameter property
338+
// for optional parameter properties
339+
// and also for non-optional initialized parameters that aren't a parameter property
340+
// these types may need to add `undefined`.
339341
const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter &&
340-
resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration);
342+
(resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration) ||
343+
resolver.isOptionalUninitializedParameterProperty(declaration as ParameterDeclaration));
341344
if (type && !shouldUseResolverType) {
342345
// Write the type
343346
emitType(type);

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2814,6 +2814,7 @@ namespace ts {
28142814
collectLinkedAliases(node: Identifier): Node[];
28152815
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
28162816
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
2817+
isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;
28172818
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
28182819
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
28192820
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//// [declarationEmitParameterProperty.ts]
2+
export class Foo {
3+
constructor(public bar?: string) {
4+
}
5+
}
6+
7+
8+
//// [declarationEmitParameterProperty.js]
9+
"use strict";
10+
exports.__esModule = true;
11+
var Foo = (function () {
12+
function Foo(bar) {
13+
this.bar = bar;
14+
}
15+
return Foo;
16+
}());
17+
exports.Foo = Foo;
18+
19+
20+
//// [declarationEmitParameterProperty.d.ts]
21+
export declare class Foo {
22+
bar: string | undefined;
23+
constructor(bar?: string | undefined);
24+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/compiler/declarationEmitParameterProperty.ts ===
2+
export class Foo {
3+
>Foo : Symbol(Foo, Decl(declarationEmitParameterProperty.ts, 0, 0))
4+
5+
constructor(public bar?: string) {
6+
>bar : Symbol(Foo.bar, Decl(declarationEmitParameterProperty.ts, 1, 14))
7+
}
8+
}
9+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/compiler/declarationEmitParameterProperty.ts ===
2+
export class Foo {
3+
>Foo : Foo
4+
5+
constructor(public bar?: string) {
6+
>bar : string | undefined
7+
}
8+
}
9+

tests/baselines/reference/optionalMethods.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,12 @@ interface Foo {
131131
}
132132
declare function test1(x: Foo): void;
133133
declare class Bar {
134-
d: number;
134+
d: number | undefined;
135135
e: number;
136136
a: number;
137137
b?: number;
138138
c?: number | undefined;
139-
constructor(d?: number, e?: number);
139+
constructor(d?: number | undefined, e?: number);
140140
f(): number;
141141
g?(): number;
142142
h?(): number;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @strictNullChecks: true
2+
// @declaration: true
3+
export class Foo {
4+
constructor(public bar?: string) {
5+
}
6+
}

0 commit comments

Comments
 (0)