Skip to content

Commit a38feac

Browse files
committed
Fix issue microsoft#22923
1 parent 9b558f9 commit a38feac

12 files changed

+136
-1
lines changed

src/compiler/checker.ts

+8
Original file line numberDiff line numberDiff line change
@@ -16409,6 +16409,9 @@ namespace ts {
1640916409
if (suggestion !== undefined) {
1641016410
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
1641116411
}
16412+
else if (isPromiseLike(containingType)) {
16413+
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_await_the_1, declarationNameToString(propNode), typeToString(containingType));
16414+
}
1641216415
else {
1641316416
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
1641416417
}
@@ -16420,6 +16423,11 @@ namespace ts {
1642016423
return suggestion && symbolName(suggestion);
1642116424
}
1642216425

16426+
function isPromiseLike(type: Type, reportErrors = false): boolean {
16427+
const types: Type[] = (type.flags & TypeFlags.Union) ? (type as UnionType).types : [type];
16428+
return types.some(t => isReferenceToType(t, getGlobalPromiseType(reportErrors)));
16429+
}
16430+
1642316431
function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string {
1642416432
Debug.assert(outerName !== undefined, "outername should always be defined");
1642516433
const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => {

src/compiler/diagnosticMessages.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -2000,7 +2000,10 @@
20002000
"category": "Error",
20012001
"code": 2569
20022002
},
2003-
2003+
"Property '{0}' does not exist on type '{1}'. Did you forget to await the '{1}'?": {
2004+
"category": "Error",
2005+
"code": 2570
2006+
},
20042007
"JSX element attributes type '{0}' may not be a union type.": {
20052008
"category": "Error",
20062009
"code": 2600
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/compiler/missingPropertyOfPromise.ts(2,7): error TS2570: Property 'toLowerCase' does not exist on type 'Promise<string>'. Did you forget to await the 'Promise<string>'?
2+
3+
4+
==== tests/cases/compiler/missingPropertyOfPromise.ts (1 errors) ====
5+
function f(x: Promise<string>) {
6+
x.toLowerCase();
7+
~~~~~~~~~~~
8+
!!! error TS2570: Property 'toLowerCase' does not exist on type 'Promise<string>'. Did you forget to await the 'Promise<string>'?
9+
}
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [missingPropertyOfPromise.ts]
2+
function f(x: Promise<string>) {
3+
x.toLowerCase();
4+
}
5+
6+
7+
//// [missingPropertyOfPromise.js]
8+
function f(x) {
9+
x.toLowerCase();
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/compiler/missingPropertyOfPromise.ts ===
2+
function f(x: Promise<string>) {
3+
>f : Symbol(f, Decl(missingPropertyOfPromise.ts, 0, 0))
4+
>x : Symbol(x, Decl(missingPropertyOfPromise.ts, 0, 11))
5+
>Promise : Symbol(Promise, Decl(lib.d.ts, --, --))
6+
7+
x.toLowerCase();
8+
>x : Symbol(x, Decl(missingPropertyOfPromise.ts, 0, 11))
9+
}
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/compiler/missingPropertyOfPromise.ts ===
2+
function f(x: Promise<string>) {
3+
>f : (x: Promise<string>) => void
4+
>x : Promise<string>
5+
>Promise : Promise<T>
6+
7+
x.toLowerCase();
8+
>x.toLowerCase() : any
9+
>x.toLowerCase : any
10+
>x : Promise<string>
11+
>toLowerCase : any
12+
}
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
tests/cases/compiler/missingPropertyOfPromiseUnion.ts(6,7): error TS2570: Property 'toLowerCase' does not exist on type 'Foo | Promise<Foo>'. Did you forget to await the 'Foo | Promise<Foo>'?
2+
Property 'toLowerCase' does not exist on type 'Foo'.
3+
4+
5+
==== tests/cases/compiler/missingPropertyOfPromiseUnion.ts (1 errors) ====
6+
interface Foo {
7+
method();
8+
}
9+
10+
function f(x: Promise<Foo> | Foo) {
11+
x.toLowerCase();
12+
~~~~~~~~~~~
13+
!!! error TS2570: Property 'toLowerCase' does not exist on type 'Foo | Promise<Foo>'. Did you forget to await the 'Foo | Promise<Foo>'?
14+
!!! error TS2570: Property 'toLowerCase' does not exist on type 'Foo'.
15+
}
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [missingPropertyOfPromiseUnion.ts]
2+
interface Foo {
3+
method();
4+
}
5+
6+
function f(x: Promise<Foo> | Foo) {
7+
x.toLowerCase();
8+
}
9+
10+
11+
//// [missingPropertyOfPromiseUnion.js]
12+
function f(x) {
13+
x.toLowerCase();
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== tests/cases/compiler/missingPropertyOfPromiseUnion.ts ===
2+
interface Foo {
3+
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseUnion.ts, 0, 0))
4+
5+
method();
6+
>method : Symbol(Foo.method, Decl(missingPropertyOfPromiseUnion.ts, 0, 15))
7+
}
8+
9+
function f(x: Promise<Foo> | Foo) {
10+
>f : Symbol(f, Decl(missingPropertyOfPromiseUnion.ts, 2, 1))
11+
>x : Symbol(x, Decl(missingPropertyOfPromiseUnion.ts, 4, 11))
12+
>Promise : Symbol(Promise, Decl(lib.d.ts, --, --))
13+
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseUnion.ts, 0, 0))
14+
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseUnion.ts, 0, 0))
15+
16+
x.toLowerCase();
17+
>x : Symbol(x, Decl(missingPropertyOfPromiseUnion.ts, 4, 11))
18+
}
19+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/missingPropertyOfPromiseUnion.ts ===
2+
interface Foo {
3+
>Foo : Foo
4+
5+
method();
6+
>method : () => any
7+
}
8+
9+
function f(x: Promise<Foo> | Foo) {
10+
>f : (x: Foo | Promise<Foo>) => void
11+
>x : Foo | Promise<Foo>
12+
>Promise : Promise<T>
13+
>Foo : Foo
14+
>Foo : Foo
15+
16+
x.toLowerCase();
17+
>x.toLowerCase() : any
18+
>x.toLowerCase : any
19+
>x : Foo | Promise<Foo>
20+
>toLowerCase : any
21+
}
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function f(x: Promise<string>) {
2+
x.toLowerCase();
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
interface Foo {
2+
method();
3+
}
4+
5+
function f(x: Promise<Foo> | Foo) {
6+
x.toLowerCase();
7+
}

0 commit comments

Comments
 (0)