Skip to content

Commit 5c8d763

Browse files
authored
fix(44448): disallow 'delete' operator for optional properties (#44612)
1 parent 4c19873 commit 5c8d763

16 files changed

+841
-48
lines changed

src/compiler/checker.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -31409,8 +31409,9 @@ namespace ts {
3140931409
}
3141031410

3141131411
function checkDeleteExpressionMustBeOptional(expr: AccessExpression, type: Type) {
31412-
const AnyOrUnknownOrNeverFlags = TypeFlags.AnyOrUnknown | TypeFlags.Never;
31413-
if (strictNullChecks && !(type.flags & AnyOrUnknownOrNeverFlags) && !(getFalsyFlags(type) & TypeFlags.Undefined)) {
31412+
if (strictNullChecks &&
31413+
!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) &&
31414+
!(exactOptionalPropertyTypes ? 0 : getFalsyFlags(type) & TypeFlags.Undefined)) {
3141431415
error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional);
3141531416
}
3141631417
}

src/testRunner/compilerRunner.ts

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ namespace Harness {
136136
"skipDefaultLibCheck",
137137
"preserveConstEnums",
138138
"skipLibCheck",
139+
"exactOptionalPropertyTypes"
139140
];
140141
private fileName: string;
141142
private justName: string;

tests/baselines/reference/deleteExpressionMustBeOptional(strict=false).errors.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ tests/cases/compiler/deleteExpressionMustBeOptional.ts(34,10): error TS2339: Pro
4343
delete a.b
4444

4545
delete b.a
46-
delete b.b
46+
delete b.b
47+

tests/baselines/reference/deleteExpressionMustBeOptional(strict=false).js

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ delete a.a
3838
delete a.b
3939

4040
delete b.a
41-
delete b.b
41+
delete b.b
42+
4243

4344
//// [deleteExpressionMustBeOptional.js]
4445
delete f.a;

tests/baselines/reference/deleteExpressionMustBeOptional(strict=true).errors.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ tests/cases/compiler/deleteExpressionMustBeOptional.ts(34,10): error TS2339: Pro
4949
delete a.b
5050

5151
delete b.a
52-
delete b.b
52+
delete b.b
53+

tests/baselines/reference/deleteExpressionMustBeOptional(strict=true).js

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ delete a.a
3838
delete a.b
3939

4040
delete b.a
41-
delete b.b
41+
delete b.b
42+
4243

4344
//// [deleteExpressionMustBeOptional.js]
4445
"use strict";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts(25,8): error TS2790: The operand of a 'delete' operator must be optional.
2+
tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts(27,8): error TS2790: The operand of a 'delete' operator must be optional.
3+
tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts(34,10): error TS2339: Property 'j' does not exist on type 'Foo'.
4+
5+
6+
==== tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts (3 errors) ====
7+
interface Foo {
8+
a: number
9+
b: number | undefined
10+
c: number | null
11+
d?: number
12+
e: number | undefined | null
13+
f?: number | undefined | null
14+
g: unknown
15+
h: any
16+
i: never
17+
}
18+
19+
interface AA {
20+
[s: string]: number
21+
}
22+
23+
type BB = {
24+
[P in keyof any]: number
25+
}
26+
27+
declare const f: Foo
28+
declare const a: AA
29+
declare const b: BB
30+
31+
delete f.a
32+
~~~
33+
!!! error TS2790: The operand of a 'delete' operator must be optional.
34+
delete f.b
35+
delete f.c
36+
~~~
37+
!!! error TS2790: The operand of a 'delete' operator must be optional.
38+
delete f.d
39+
delete f.e
40+
delete f.f
41+
delete f.g
42+
delete f.h
43+
delete f.i
44+
delete f.j
45+
~
46+
!!! error TS2339: Property 'j' does not exist on type 'Foo'.
47+
48+
delete a.a
49+
delete a.b
50+
51+
delete b.a
52+
delete b.b
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//// [deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts]
2+
interface Foo {
3+
a: number
4+
b: number | undefined
5+
c: number | null
6+
d?: number
7+
e: number | undefined | null
8+
f?: number | undefined | null
9+
g: unknown
10+
h: any
11+
i: never
12+
}
13+
14+
interface AA {
15+
[s: string]: number
16+
}
17+
18+
type BB = {
19+
[P in keyof any]: number
20+
}
21+
22+
declare const f: Foo
23+
declare const a: AA
24+
declare const b: BB
25+
26+
delete f.a
27+
delete f.b
28+
delete f.c
29+
delete f.d
30+
delete f.e
31+
delete f.f
32+
delete f.g
33+
delete f.h
34+
delete f.i
35+
delete f.j
36+
37+
delete a.a
38+
delete a.b
39+
40+
delete b.a
41+
delete b.b
42+
43+
44+
//// [deleteExpressionMustBeOptional_exactOptionalPropertyTypes.js]
45+
delete f.a;
46+
delete f.b;
47+
delete f.c;
48+
delete f.d;
49+
delete f.e;
50+
delete f.f;
51+
delete f.g;
52+
delete f.h;
53+
delete f.i;
54+
delete f.j;
55+
delete a.a;
56+
delete a.b;
57+
delete b.a;
58+
delete b.b;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
=== tests/cases/compiler/deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts ===
2+
interface Foo {
3+
>Foo : Symbol(Foo, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 0, 0))
4+
5+
a: number
6+
>a : Symbol(Foo.a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 0, 15))
7+
8+
b: number | undefined
9+
>b : Symbol(Foo.b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 1, 13))
10+
11+
c: number | null
12+
>c : Symbol(Foo.c, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 2, 25))
13+
14+
d?: number
15+
>d : Symbol(Foo.d, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 3, 20))
16+
17+
e: number | undefined | null
18+
>e : Symbol(Foo.e, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 4, 14))
19+
20+
f?: number | undefined | null
21+
>f : Symbol(Foo.f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 5, 32))
22+
23+
g: unknown
24+
>g : Symbol(Foo.g, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 6, 33))
25+
26+
h: any
27+
>h : Symbol(Foo.h, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 7, 14))
28+
29+
i: never
30+
>i : Symbol(Foo.i, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 8, 10))
31+
}
32+
33+
interface AA {
34+
>AA : Symbol(AA, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 10, 1))
35+
36+
[s: string]: number
37+
>s : Symbol(s, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 13, 5))
38+
}
39+
40+
type BB = {
41+
>BB : Symbol(BB, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 14, 1))
42+
43+
[P in keyof any]: number
44+
>P : Symbol(P, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 17, 5))
45+
}
46+
47+
declare const f: Foo
48+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
49+
>Foo : Symbol(Foo, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 0, 0))
50+
51+
declare const a: AA
52+
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 21, 13))
53+
>AA : Symbol(AA, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 10, 1))
54+
55+
declare const b: BB
56+
>b : Symbol(b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
57+
>BB : Symbol(BB, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 14, 1))
58+
59+
delete f.a
60+
>f.a : Symbol(Foo.a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 0, 15))
61+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
62+
>a : Symbol(Foo.a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 0, 15))
63+
64+
delete f.b
65+
>f.b : Symbol(Foo.b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 1, 13))
66+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
67+
>b : Symbol(Foo.b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 1, 13))
68+
69+
delete f.c
70+
>f.c : Symbol(Foo.c, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 2, 25))
71+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
72+
>c : Symbol(Foo.c, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 2, 25))
73+
74+
delete f.d
75+
>f.d : Symbol(Foo.d, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 3, 20))
76+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
77+
>d : Symbol(Foo.d, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 3, 20))
78+
79+
delete f.e
80+
>f.e : Symbol(Foo.e, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 4, 14))
81+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
82+
>e : Symbol(Foo.e, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 4, 14))
83+
84+
delete f.f
85+
>f.f : Symbol(Foo.f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 5, 32))
86+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
87+
>f : Symbol(Foo.f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 5, 32))
88+
89+
delete f.g
90+
>f.g : Symbol(Foo.g, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 6, 33))
91+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
92+
>g : Symbol(Foo.g, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 6, 33))
93+
94+
delete f.h
95+
>f.h : Symbol(Foo.h, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 7, 14))
96+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
97+
>h : Symbol(Foo.h, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 7, 14))
98+
99+
delete f.i
100+
>f.i : Symbol(Foo.i, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 8, 10))
101+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
102+
>i : Symbol(Foo.i, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 8, 10))
103+
104+
delete f.j
105+
>f : Symbol(f, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 20, 13))
106+
107+
delete a.a
108+
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 21, 13))
109+
110+
delete a.b
111+
>a : Symbol(a, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 21, 13))
112+
113+
delete b.a
114+
>b : Symbol(b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
115+
116+
delete b.b
117+
>b : Symbol(b, Decl(deleteExpressionMustBeOptional_exactOptionalPropertyTypes.ts, 22, 13))
118+

0 commit comments

Comments
 (0)