Skip to content

Commit 5d60697

Browse files
Copilotjakebailey
andauthored
Fix parameter-property with default value emitting T | undefined instead of T (#1479)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: jakebailey <[email protected]>
1 parent 5cdf239 commit 5d60697

21 files changed

+306
-51
lines changed

internal/checker/emitresolver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ func (r *emitResolver) declaredParameterTypeContainsUndefined(parameter *ast.Nod
546546
func (r *emitResolver) isOptionalUninitializedParameterProperty(parameter *ast.Node) bool {
547547
return r.checker.strictNullChecks &&
548548
r.isOptionalParameter(parameter) &&
549-
( /*isJSDocParameterTag(parameter) ||*/ parameter.Initializer() != nil) && // !!! TODO: JSDoc support
549+
( /*isJSDocParameterTag(parameter) ||*/ parameter.Initializer() == nil) && // !!! TODO: JSDoc support
550550
ast.HasSyntacticModifier(parameter, ast.ModifierFlagsParameterPropertyModifier)
551551
}
552552

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [tests/cases/compiler/parameterPropertyWithDefaultValue.ts] ////
2+
3+
//// [parameterPropertyWithDefaultValue.ts]
4+
export class SomeClass {
5+
constructor(readonly timestamp = new Date()) {}
6+
}
7+
8+
//// [parameterPropertyWithDefaultValue.js]
9+
export class SomeClass {
10+
timestamp;
11+
constructor(timestamp = new Date()) {
12+
this.timestamp = timestamp;
13+
}
14+
}
15+
16+
17+
//// [parameterPropertyWithDefaultValue.d.ts]
18+
export declare class SomeClass {
19+
readonly timestamp: Date;
20+
constructor(timestamp?: Date);
21+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [tests/cases/compiler/parameterPropertyWithDefaultValue.ts] ////
2+
3+
=== parameterPropertyWithDefaultValue.ts ===
4+
export class SomeClass {
5+
>SomeClass : Symbol(SomeClass, Decl(parameterPropertyWithDefaultValue.ts, 0, 0))
6+
7+
constructor(readonly timestamp = new Date()) {}
8+
>timestamp : Symbol(timestamp, Decl(parameterPropertyWithDefaultValue.ts, 1, 14))
9+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//// [tests/cases/compiler/parameterPropertyWithDefaultValue.ts] ////
2+
3+
=== parameterPropertyWithDefaultValue.ts ===
4+
export class SomeClass {
5+
>SomeClass : SomeClass
6+
7+
constructor(readonly timestamp = new Date()) {}
8+
>timestamp : Date
9+
>new Date() : Date
10+
>Date : DateConstructor
11+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//// [tests/cases/compiler/parameterPropertyWithDefaultValueExtended.ts] ////
2+
3+
//// [parameterPropertyWithDefaultValueExtended.ts]
4+
// Test with default value - should not have undefined
5+
export class WithDefault {
6+
constructor(readonly timestamp = new Date()) {}
7+
}
8+
9+
// Test without default value but optional - should have undefined
10+
export class WithoutDefault {
11+
constructor(readonly timestamp?: Date) {}
12+
}
13+
14+
// Test with explicit undefined type - should keep it
15+
export class ExplicitUndefined {
16+
constructor(readonly timestamp: Date | undefined = new Date()) {}
17+
}
18+
19+
// Test private parameter property with default value
20+
export class PrivateWithDefault {
21+
constructor(private timestamp = new Date()) {}
22+
}
23+
24+
// Test public parameter property with default value
25+
export class PublicWithDefault {
26+
constructor(public timestamp = new Date()) {}
27+
}
28+
29+
//// [parameterPropertyWithDefaultValueExtended.js]
30+
// Test with default value - should not have undefined
31+
export class WithDefault {
32+
timestamp;
33+
constructor(timestamp = new Date()) {
34+
this.timestamp = timestamp;
35+
}
36+
}
37+
// Test without default value but optional - should have undefined
38+
export class WithoutDefault {
39+
timestamp;
40+
constructor(timestamp) {
41+
this.timestamp = timestamp;
42+
}
43+
}
44+
// Test with explicit undefined type - should keep it
45+
export class ExplicitUndefined {
46+
timestamp;
47+
constructor(timestamp = new Date()) {
48+
this.timestamp = timestamp;
49+
}
50+
}
51+
// Test private parameter property with default value
52+
export class PrivateWithDefault {
53+
timestamp;
54+
constructor(timestamp = new Date()) {
55+
this.timestamp = timestamp;
56+
}
57+
}
58+
// Test public parameter property with default value
59+
export class PublicWithDefault {
60+
timestamp;
61+
constructor(timestamp = new Date()) {
62+
this.timestamp = timestamp;
63+
}
64+
}
65+
66+
67+
//// [parameterPropertyWithDefaultValueExtended.d.ts]
68+
// Test with default value - should not have undefined
69+
export declare class WithDefault {
70+
readonly timestamp: Date;
71+
constructor(timestamp?: Date);
72+
}
73+
// Test without default value but optional - should have undefined
74+
export declare class WithoutDefault {
75+
readonly timestamp?: Date | undefined;
76+
constructor(timestamp?: Date | undefined);
77+
}
78+
// Test with explicit undefined type - should keep it
79+
export declare class ExplicitUndefined {
80+
readonly timestamp: Date | undefined;
81+
constructor(timestamp?: Date | undefined);
82+
}
83+
// Test private parameter property with default value
84+
export declare class PrivateWithDefault {
85+
private timestamp;
86+
constructor(timestamp?: Date);
87+
}
88+
// Test public parameter property with default value
89+
export declare class PublicWithDefault {
90+
timestamp: Date;
91+
constructor(timestamp?: Date);
92+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//// [tests/cases/compiler/parameterPropertyWithDefaultValueExtended.ts] ////
2+
3+
=== parameterPropertyWithDefaultValueExtended.ts ===
4+
// Test with default value - should not have undefined
5+
export class WithDefault {
6+
>WithDefault : Symbol(WithDefault, Decl(parameterPropertyWithDefaultValueExtended.ts, 0, 0))
7+
8+
constructor(readonly timestamp = new Date()) {}
9+
>timestamp : Symbol(timestamp, Decl(parameterPropertyWithDefaultValueExtended.ts, 2, 14))
10+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
11+
}
12+
13+
// Test without default value but optional - should have undefined
14+
export class WithoutDefault {
15+
>WithoutDefault : Symbol(WithoutDefault, Decl(parameterPropertyWithDefaultValueExtended.ts, 3, 1))
16+
17+
constructor(readonly timestamp?: Date) {}
18+
>timestamp : Symbol(timestamp, Decl(parameterPropertyWithDefaultValueExtended.ts, 7, 14))
19+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
20+
}
21+
22+
// Test with explicit undefined type - should keep it
23+
export class ExplicitUndefined {
24+
>ExplicitUndefined : Symbol(ExplicitUndefined, Decl(parameterPropertyWithDefaultValueExtended.ts, 8, 1))
25+
26+
constructor(readonly timestamp: Date | undefined = new Date()) {}
27+
>timestamp : Symbol(timestamp, Decl(parameterPropertyWithDefaultValueExtended.ts, 12, 14))
28+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
29+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
30+
}
31+
32+
// Test private parameter property with default value
33+
export class PrivateWithDefault {
34+
>PrivateWithDefault : Symbol(PrivateWithDefault, Decl(parameterPropertyWithDefaultValueExtended.ts, 13, 1))
35+
36+
constructor(private timestamp = new Date()) {}
37+
>timestamp : Symbol(timestamp, Decl(parameterPropertyWithDefaultValueExtended.ts, 17, 14))
38+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
39+
}
40+
41+
// Test public parameter property with default value
42+
export class PublicWithDefault {
43+
>PublicWithDefault : Symbol(PublicWithDefault, Decl(parameterPropertyWithDefaultValueExtended.ts, 18, 1))
44+
45+
constructor(public timestamp = new Date()) {}
46+
>timestamp : Symbol(timestamp, Decl(parameterPropertyWithDefaultValueExtended.ts, 22, 14))
47+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
48+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//// [tests/cases/compiler/parameterPropertyWithDefaultValueExtended.ts] ////
2+
3+
=== parameterPropertyWithDefaultValueExtended.ts ===
4+
// Test with default value - should not have undefined
5+
export class WithDefault {
6+
>WithDefault : WithDefault
7+
8+
constructor(readonly timestamp = new Date()) {}
9+
>timestamp : Date
10+
>new Date() : Date
11+
>Date : DateConstructor
12+
}
13+
14+
// Test without default value but optional - should have undefined
15+
export class WithoutDefault {
16+
>WithoutDefault : WithoutDefault
17+
18+
constructor(readonly timestamp?: Date) {}
19+
>timestamp : Date | undefined
20+
}
21+
22+
// Test with explicit undefined type - should keep it
23+
export class ExplicitUndefined {
24+
>ExplicitUndefined : ExplicitUndefined
25+
26+
constructor(readonly timestamp: Date | undefined = new Date()) {}
27+
>timestamp : Date | undefined
28+
>new Date() : Date
29+
>Date : DateConstructor
30+
}
31+
32+
// Test private parameter property with default value
33+
export class PrivateWithDefault {
34+
>PrivateWithDefault : PrivateWithDefault
35+
36+
constructor(private timestamp = new Date()) {}
37+
>timestamp : Date
38+
>new Date() : Date
39+
>Date : DateConstructor
40+
}
41+
42+
// Test public parameter property with default value
43+
export class PublicWithDefault {
44+
>PublicWithDefault : PublicWithDefault
45+
46+
constructor(public timestamp = new Date()) {}
47+
>timestamp : Date
48+
>new Date() : Date
49+
>Date : DateConstructor
50+
}

testdata/baselines/reference/submodule/compiler/declarationEmitCastReusesTypeNode1(strictnullchecks=true).js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export declare function fnWithRequiredDefaultParam(p: {
4949
export declare class C {
5050
ctorField: {
5151
name: string;
52-
} | undefined;
52+
};
5353
field: {
5454
name: string;
5555
};
@@ -67,7 +67,7 @@ export declare class C {
6767
}, req: number): void;
6868
constructor(ctorField?: {
6969
name: string;
70-
} | undefined);
70+
});
7171
get x(): {
7272
name: string;
7373
};

testdata/baselines/reference/submodule/compiler/declarationEmitCastReusesTypeNode1(strictnullchecks=true).js.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
- set x(v: P);
3333
+ ctorField: {
3434
+ name: string;
35-
+ } | undefined;
35+
+ };
3636
+ field: {
3737
+ name: string;
3838
+ };
@@ -50,7 +50,7 @@
5050
+ }, req: number): void;
5151
+ constructor(ctorField?: {
5252
+ name: string;
53-
+ } | undefined);
53+
+ });
5454
+ get x(): {
5555
+ name: string;
5656
+ };

testdata/baselines/reference/submodule/compiler/declarationEmitCastReusesTypeNode2(strictnullchecks=true).js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export declare function fnWithRequiredDefaultParam(p: {
4444
export declare class C {
4545
ctorField: {
4646
name: string;
47-
} | undefined;
47+
};
4848
field: {
4949
name: string;
5050
};
@@ -62,7 +62,7 @@ export declare class C {
6262
}, req: number): void;
6363
constructor(ctorField?: {
6464
name: string;
65-
} | undefined);
65+
});
6666
get x(): {
6767
name: string;
6868
};

0 commit comments

Comments
 (0)