Skip to content

Commit a5e0385

Browse files
authored
Avoid reporting EPC on unannotated using declarations (microsoft#59590)
1 parent 0ae769a commit a5e0385

11 files changed

+559
-2
lines changed

src/compiler/checker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -44105,14 +44105,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4410544105
const globalDisposableType = getGlobalDisposableType(/*reportErrors*/ true);
4410644106
if (globalAsyncDisposableType !== emptyObjectType && globalDisposableType !== emptyObjectType) {
4410744107
const optionalDisposableType = getUnionType([globalAsyncDisposableType, globalDisposableType, nullType, undefinedType]);
44108-
checkTypeAssignableTo(initializerType, optionalDisposableType, initializer, Diagnostics.The_initializer_of_an_await_using_declaration_must_be_either_an_object_with_a_Symbol_asyncDispose_or_Symbol_dispose_method_or_be_null_or_undefined);
44108+
checkTypeAssignableTo(widenTypeForVariableLikeDeclaration(initializerType, node), optionalDisposableType, initializer, Diagnostics.The_initializer_of_an_await_using_declaration_must_be_either_an_object_with_a_Symbol_asyncDispose_or_Symbol_dispose_method_or_be_null_or_undefined);
4410944109
}
4411044110
}
4411144111
else if (blockScopeKind === NodeFlags.Using) {
4411244112
const globalDisposableType = getGlobalDisposableType(/*reportErrors*/ true);
4411344113
if (globalDisposableType !== emptyObjectType) {
4411444114
const optionalDisposableType = getUnionType([globalDisposableType, nullType, undefinedType]);
44115-
checkTypeAssignableTo(initializerType, optionalDisposableType, initializer, Diagnostics.The_initializer_of_a_using_declaration_must_be_either_an_object_with_a_Symbol_dispose_method_or_be_null_or_undefined);
44115+
checkTypeAssignableTo(widenTypeForVariableLikeDeclaration(initializerType, node), optionalDisposableType, initializer, Diagnostics.The_initializer_of_a_using_declaration_must_be_either_an_object_with_a_Symbol_dispose_method_or_be_null_or_undefined);
4411644116
}
4411744117
}
4411844118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
usingDeclarationsWithObjectLiterals1.ts(15,62): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type 'MyDisposable'.
2+
usingDeclarationsWithObjectLiterals1.ts(36,7): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type 'MyAsyncDisposable'.
3+
4+
5+
==== usingDeclarationsWithObjectLiterals1.ts (2 errors) ====
6+
interface MyDisposable {
7+
value: number;
8+
[Symbol.dispose](): void;
9+
}
10+
11+
{
12+
using _ = { [Symbol.dispose]() {} };
13+
}
14+
15+
{
16+
using _ = { [Symbol.dispose]() {}, value: 1 };
17+
}
18+
19+
{
20+
using _: MyDisposable = { [Symbol.dispose]() {}, value: 1, extra: "foo" };
21+
~~~~~
22+
!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type 'MyDisposable'.
23+
}
24+
25+
interface MyAsyncDisposable {
26+
value: number;
27+
[Symbol.asyncDispose](): Promise<void>;
28+
}
29+
30+
async function f() {
31+
{
32+
await using _ = { async [Symbol.asyncDispose]() {} };
33+
}
34+
35+
{
36+
await using _ = { async [Symbol.asyncDispose]() {}, value: 1 };
37+
}
38+
39+
{
40+
await using _: MyAsyncDisposable = {
41+
async [Symbol.asyncDispose]() {},
42+
value: 1,
43+
extra: "foo",
44+
~~~~~
45+
!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type 'MyAsyncDisposable'.
46+
};
47+
}
48+
}
49+
50+
export {};
51+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsWithObjectLiterals1.ts] ////
2+
3+
=== usingDeclarationsWithObjectLiterals1.ts ===
4+
interface MyDisposable {
5+
>MyDisposable : Symbol(MyDisposable, Decl(usingDeclarationsWithObjectLiterals1.ts, 0, 0))
6+
7+
value: number;
8+
>value : Symbol(MyDisposable.value, Decl(usingDeclarationsWithObjectLiterals1.ts, 0, 24))
9+
10+
[Symbol.dispose](): void;
11+
>[Symbol.dispose] : Symbol(MyDisposable[Symbol.dispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 1, 16))
12+
>Symbol.dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
13+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
14+
>dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
15+
}
16+
17+
{
18+
using _ = { [Symbol.dispose]() {} };
19+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals1.ts, 6, 7))
20+
>[Symbol.dispose] : Symbol([Symbol.dispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 6, 13))
21+
>Symbol.dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
22+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
23+
>dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
24+
}
25+
26+
{
27+
using _ = { [Symbol.dispose]() {}, value: 1 };
28+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals1.ts, 10, 7))
29+
>[Symbol.dispose] : Symbol([Symbol.dispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 10, 13))
30+
>Symbol.dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
31+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
32+
>dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
33+
>value : Symbol(value, Decl(usingDeclarationsWithObjectLiterals1.ts, 10, 36))
34+
}
35+
36+
{
37+
using _: MyDisposable = { [Symbol.dispose]() {}, value: 1, extra: "foo" };
38+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals1.ts, 14, 7))
39+
>MyDisposable : Symbol(MyDisposable, Decl(usingDeclarationsWithObjectLiterals1.ts, 0, 0))
40+
>[Symbol.dispose] : Symbol([Symbol.dispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 14, 27))
41+
>Symbol.dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
42+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
43+
>dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
44+
>value : Symbol(value, Decl(usingDeclarationsWithObjectLiterals1.ts, 14, 50))
45+
>extra : Symbol(extra, Decl(usingDeclarationsWithObjectLiterals1.ts, 14, 60))
46+
}
47+
48+
interface MyAsyncDisposable {
49+
>MyAsyncDisposable : Symbol(MyAsyncDisposable, Decl(usingDeclarationsWithObjectLiterals1.ts, 15, 1))
50+
51+
value: number;
52+
>value : Symbol(MyAsyncDisposable.value, Decl(usingDeclarationsWithObjectLiterals1.ts, 17, 29))
53+
54+
[Symbol.asyncDispose](): Promise<void>;
55+
>[Symbol.asyncDispose] : Symbol(MyAsyncDisposable[Symbol.asyncDispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 18, 16))
56+
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
57+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
58+
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
59+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
60+
}
61+
62+
async function f() {
63+
>f : Symbol(f, Decl(usingDeclarationsWithObjectLiterals1.ts, 20, 1))
64+
{
65+
await using _ = { async [Symbol.asyncDispose]() {} };
66+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals1.ts, 24, 15))
67+
>[Symbol.asyncDispose] : Symbol([Symbol.asyncDispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 24, 21))
68+
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
69+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
70+
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
71+
}
72+
73+
{
74+
await using _ = { async [Symbol.asyncDispose]() {}, value: 1 };
75+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals1.ts, 28, 15))
76+
>[Symbol.asyncDispose] : Symbol([Symbol.asyncDispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 28, 21))
77+
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
78+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
79+
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
80+
>value : Symbol(value, Decl(usingDeclarationsWithObjectLiterals1.ts, 28, 55))
81+
}
82+
83+
{
84+
await using _: MyAsyncDisposable = {
85+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals1.ts, 32, 15))
86+
>MyAsyncDisposable : Symbol(MyAsyncDisposable, Decl(usingDeclarationsWithObjectLiterals1.ts, 15, 1))
87+
88+
async [Symbol.asyncDispose]() {},
89+
>[Symbol.asyncDispose] : Symbol([Symbol.asyncDispose], Decl(usingDeclarationsWithObjectLiterals1.ts, 32, 40))
90+
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
91+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
92+
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
93+
94+
value: 1,
95+
>value : Symbol(value, Decl(usingDeclarationsWithObjectLiterals1.ts, 33, 39))
96+
97+
extra: "foo",
98+
>extra : Symbol(extra, Decl(usingDeclarationsWithObjectLiterals1.ts, 34, 15))
99+
100+
};
101+
}
102+
}
103+
104+
export {};
105+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsWithObjectLiterals1.ts] ////
2+
3+
=== usingDeclarationsWithObjectLiterals1.ts ===
4+
interface MyDisposable {
5+
value: number;
6+
>value : number
7+
> : ^^^^^^
8+
9+
[Symbol.dispose](): void;
10+
>[Symbol.dispose] : () => void
11+
> : ^^^^^^
12+
>Symbol.dispose : unique symbol
13+
> : ^^^^^^^^^^^^^
14+
>Symbol : SymbolConstructor
15+
> : ^^^^^^^^^^^^^^^^^
16+
>dispose : unique symbol
17+
> : ^^^^^^^^^^^^^
18+
}
19+
20+
{
21+
using _ = { [Symbol.dispose]() {} };
22+
>_ : { [Symbol.dispose](): void; }
23+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
>{ [Symbol.dispose]() {} } : { [Symbol.dispose](): void; }
25+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
>[Symbol.dispose] : () => void
27+
> : ^^^^^^^^^^
28+
>Symbol.dispose : unique symbol
29+
> : ^^^^^^^^^^^^^
30+
>Symbol : SymbolConstructor
31+
> : ^^^^^^^^^^^^^^^^^
32+
>dispose : unique symbol
33+
> : ^^^^^^^^^^^^^
34+
}
35+
36+
{
37+
using _ = { [Symbol.dispose]() {}, value: 1 };
38+
>_ : { [Symbol.dispose](): void; value: number; }
39+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40+
>{ [Symbol.dispose]() {}, value: 1 } : { [Symbol.dispose](): void; value: number; }
41+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42+
>[Symbol.dispose] : () => void
43+
> : ^^^^^^^^^^
44+
>Symbol.dispose : unique symbol
45+
> : ^^^^^^^^^^^^^
46+
>Symbol : SymbolConstructor
47+
> : ^^^^^^^^^^^^^^^^^
48+
>dispose : unique symbol
49+
> : ^^^^^^^^^^^^^
50+
>value : number
51+
> : ^^^^^^
52+
>1 : 1
53+
> : ^
54+
}
55+
56+
{
57+
using _: MyDisposable = { [Symbol.dispose]() {}, value: 1, extra: "foo" };
58+
>_ : MyDisposable
59+
> : ^^^^^^^^^^^^
60+
>{ [Symbol.dispose]() {}, value: 1, extra: "foo" } : { [Symbol.dispose](): void; value: number; extra: string; }
61+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62+
>[Symbol.dispose] : () => void
63+
> : ^^^^^^^^^^
64+
>Symbol.dispose : unique symbol
65+
> : ^^^^^^^^^^^^^
66+
>Symbol : SymbolConstructor
67+
> : ^^^^^^^^^^^^^^^^^
68+
>dispose : unique symbol
69+
> : ^^^^^^^^^^^^^
70+
>value : number
71+
> : ^^^^^^
72+
>1 : 1
73+
> : ^
74+
>extra : string
75+
> : ^^^^^^
76+
>"foo" : "foo"
77+
> : ^^^^^
78+
}
79+
80+
interface MyAsyncDisposable {
81+
value: number;
82+
>value : number
83+
> : ^^^^^^
84+
85+
[Symbol.asyncDispose](): Promise<void>;
86+
>[Symbol.asyncDispose] : () => Promise<void>
87+
> : ^^^^^^
88+
>Symbol.asyncDispose : unique symbol
89+
> : ^^^^^^^^^^^^^
90+
>Symbol : SymbolConstructor
91+
> : ^^^^^^^^^^^^^^^^^
92+
>asyncDispose : unique symbol
93+
> : ^^^^^^^^^^^^^
94+
}
95+
96+
async function f() {
97+
>f : () => Promise<void>
98+
> : ^^^^^^^^^^^^^^^^^^^
99+
{
100+
await using _ = { async [Symbol.asyncDispose]() {} };
101+
>_ : { [Symbol.asyncDispose](): Promise<void>; }
102+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
103+
>{ async [Symbol.asyncDispose]() {} } : { [Symbol.asyncDispose](): Promise<void>; }
104+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105+
>[Symbol.asyncDispose] : () => Promise<void>
106+
> : ^^^^^^^^^^^^^^^^^^^
107+
>Symbol.asyncDispose : unique symbol
108+
> : ^^^^^^^^^^^^^
109+
>Symbol : SymbolConstructor
110+
> : ^^^^^^^^^^^^^^^^^
111+
>asyncDispose : unique symbol
112+
> : ^^^^^^^^^^^^^
113+
}
114+
115+
{
116+
await using _ = { async [Symbol.asyncDispose]() {}, value: 1 };
117+
>_ : { [Symbol.asyncDispose](): Promise<void>; value: number; }
118+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
119+
>{ async [Symbol.asyncDispose]() {}, value: 1 } : { [Symbol.asyncDispose](): Promise<void>; value: number; }
120+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
121+
>[Symbol.asyncDispose] : () => Promise<void>
122+
> : ^^^^^^^^^^^^^^^^^^^
123+
>Symbol.asyncDispose : unique symbol
124+
> : ^^^^^^^^^^^^^
125+
>Symbol : SymbolConstructor
126+
> : ^^^^^^^^^^^^^^^^^
127+
>asyncDispose : unique symbol
128+
> : ^^^^^^^^^^^^^
129+
>value : number
130+
> : ^^^^^^
131+
>1 : 1
132+
> : ^
133+
}
134+
135+
{
136+
await using _: MyAsyncDisposable = {
137+
>_ : MyAsyncDisposable
138+
> : ^^^^^^^^^^^^^^^^^
139+
>{ async [Symbol.asyncDispose]() {}, value: 1, extra: "foo", } : { [Symbol.asyncDispose](): Promise<void>; value: number; extra: string; }
140+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
141+
142+
async [Symbol.asyncDispose]() {},
143+
>[Symbol.asyncDispose] : () => Promise<void>
144+
> : ^^^^^^^^^^^^^^^^^^^
145+
>Symbol.asyncDispose : unique symbol
146+
> : ^^^^^^^^^^^^^
147+
>Symbol : SymbolConstructor
148+
> : ^^^^^^^^^^^^^^^^^
149+
>asyncDispose : unique symbol
150+
> : ^^^^^^^^^^^^^
151+
152+
value: 1,
153+
>value : number
154+
> : ^^^^^^
155+
>1 : 1
156+
> : ^
157+
158+
extra: "foo",
159+
>extra : string
160+
> : ^^^^^^
161+
>"foo" : "foo"
162+
> : ^^^^^
163+
164+
};
165+
}
166+
}
167+
168+
export {};
169+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsWithObjectLiterals2.ts] ////
2+
3+
=== usingDeclarationsWithObjectLiterals2.ts ===
4+
{
5+
using _ = { [Symbol.dispose]() {}, value: null };
6+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals2.ts, 1, 7))
7+
>[Symbol.dispose] : Symbol([Symbol.dispose], Decl(usingDeclarationsWithObjectLiterals2.ts, 1, 13))
8+
>Symbol.dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
9+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
10+
>dispose : Symbol(SymbolConstructor.dispose, Decl(lib.esnext.disposable.d.ts, --, --))
11+
>value : Symbol(value, Decl(usingDeclarationsWithObjectLiterals2.ts, 1, 36))
12+
}
13+
14+
async function f() {
15+
>f : Symbol(f, Decl(usingDeclarationsWithObjectLiterals2.ts, 2, 1))
16+
{
17+
await using _ = { async [Symbol.asyncDispose]() {}, value: null };
18+
>_ : Symbol(_, Decl(usingDeclarationsWithObjectLiterals2.ts, 6, 15))
19+
>[Symbol.asyncDispose] : Symbol([Symbol.asyncDispose], Decl(usingDeclarationsWithObjectLiterals2.ts, 6, 21))
20+
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
21+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
22+
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
23+
>value : Symbol(value, Decl(usingDeclarationsWithObjectLiterals2.ts, 6, 55))
24+
}
25+
}
26+
27+
export {};
28+

0 commit comments

Comments
 (0)