Skip to content

Commit

Permalink
Fix issue microsoft#22923
Browse files Browse the repository at this point in the history
  • Loading branch information
akhomchenko committed Apr 1, 2018
1 parent 9b558f9 commit 49a2599
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16409,6 +16409,9 @@ namespace ts {
if (suggestion !== undefined) {
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
}
else if (isPromiseLike(containingType)) {
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_await_the_1, declarationNameToString(propNode), typeToString(containingType));
}
else {
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
}
Expand All @@ -16420,6 +16423,12 @@ namespace ts {
return suggestion && symbolName(suggestion);
}

function isPromiseLike(type: Type, reportErrors = false): boolean {
const types: Type[] = (type.flags & TypeFlags.UnionOrIntersection)
? (type as UnionOrIntersectionType).types : [type];
return types.some(t => isReferenceToType(t, getGlobalPromiseType(reportErrors)));
}

function getSuggestionForNonexistentSymbol(location: Node, outerName: __String, meaning: SymbolFlags): string {
Debug.assert(outerName !== undefined, "outername should always be defined");
const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => {
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2000,7 +2000,10 @@
"category": "Error",
"code": 2569
},

"Property '{0}' does not exist on type '{1}'. Did you forget to await the '{1}'?": {
"category": "Error",
"code": 2570
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
Expand Down
10 changes: 10 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromise.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
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>'?


==== tests/cases/compiler/missingPropertyOfPromise.ts (1 errors) ====
function f(x: Promise<string>) {
x.toLowerCase();
~~~~~~~~~~~
!!! error TS2570: Property 'toLowerCase' does not exist on type 'Promise<string>'. Did you forget to await the 'Promise<string>'?
}

10 changes: 10 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//// [missingPropertyOfPromise.ts]
function f(x: Promise<string>) {
x.toLowerCase();
}


//// [missingPropertyOfPromise.js]
function f(x) {
x.toLowerCase();
}
10 changes: 10 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromise.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=== tests/cases/compiler/missingPropertyOfPromise.ts ===
function f(x: Promise<string>) {
>f : Symbol(f, Decl(missingPropertyOfPromise.ts, 0, 0))
>x : Symbol(x, Decl(missingPropertyOfPromise.ts, 0, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, --, --))

x.toLowerCase();
>x : Symbol(x, Decl(missingPropertyOfPromise.ts, 0, 11))
}

13 changes: 13 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromise.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
=== tests/cases/compiler/missingPropertyOfPromise.ts ===
function f(x: Promise<string>) {
>f : (x: Promise<string>) => void
>x : Promise<string>
>Promise : Promise<T>

x.toLowerCase();
>x.toLowerCase() : any
>x.toLowerCase : any
>x : Promise<string>
>toLowerCase : any
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
tests/cases/compiler/missingPropertyOfPromiseIntersection.ts(10,7): error TS2570: Property 'method' does not exist on type 'Promise<Foo> & Bar'. Did you forget to await the 'Promise<Foo> & Bar'?


==== tests/cases/compiler/missingPropertyOfPromiseIntersection.ts (1 errors) ====
interface Foo {
method();
}

interface Bar {
somethingElse();
}

function f(x: Promise<Foo> & Bar) {
x.method();
~~~~~~
!!! error TS2570: Property 'method' does not exist on type 'Promise<Foo> & Bar'. Did you forget to await the 'Promise<Foo> & Bar'?
}

18 changes: 18 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromiseIntersection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//// [missingPropertyOfPromiseIntersection.ts]
interface Foo {
method();
}

interface Bar {
somethingElse();
}

function f(x: Promise<Foo> & Bar) {
x.method();
}


//// [missingPropertyOfPromiseIntersection.js]
function f(x) {
x.method();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
=== tests/cases/compiler/missingPropertyOfPromiseIntersection.ts ===
interface Foo {
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseIntersection.ts, 0, 0))

method();
>method : Symbol(Foo.method, Decl(missingPropertyOfPromiseIntersection.ts, 0, 15))
}

interface Bar {
>Bar : Symbol(Bar, Decl(missingPropertyOfPromiseIntersection.ts, 2, 1))

somethingElse();
>somethingElse : Symbol(Bar.somethingElse, Decl(missingPropertyOfPromiseIntersection.ts, 4, 15))
}

function f(x: Promise<Foo> & Bar) {
>f : Symbol(f, Decl(missingPropertyOfPromiseIntersection.ts, 6, 1))
>x : Symbol(x, Decl(missingPropertyOfPromiseIntersection.ts, 8, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, --, --))
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseIntersection.ts, 0, 0))
>Bar : Symbol(Bar, Decl(missingPropertyOfPromiseIntersection.ts, 2, 1))

x.method();
>x : Symbol(x, Decl(missingPropertyOfPromiseIntersection.ts, 8, 11))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/missingPropertyOfPromiseIntersection.ts ===
interface Foo {
>Foo : Foo

method();
>method : () => any
}

interface Bar {
>Bar : Bar

somethingElse();
>somethingElse : () => any
}

function f(x: Promise<Foo> & Bar) {
>f : (x: Promise<Foo> & Bar) => void
>x : Promise<Foo> & Bar
>Promise : Promise<T>
>Foo : Foo
>Bar : Bar

x.method();
>x.method() : any
>x.method : any
>x : Promise<Foo> & Bar
>method : any
}

21 changes: 21 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromiseUnion.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
tests/cases/compiler/missingPropertyOfPromiseUnion.ts(11,7): error TS2570: Property 'method' does not exist on type 'Promise<Foo> | Promise<Bar>'. Did you forget to await the 'Promise<Foo> | Promise<Bar>'?
Property 'method' does not exist on type 'Promise<Foo>'.


==== tests/cases/compiler/missingPropertyOfPromiseUnion.ts (1 errors) ====
interface Foo {
method();
}

interface Bar {
method();
somethingElse();
}

function f(x: Promise<Foo> | Promise<Bar>) {
x.method();
~~~~~~
!!! error TS2570: Property 'method' does not exist on type 'Promise<Foo> | Promise<Bar>'. Did you forget to await the 'Promise<Foo> | Promise<Bar>'?
!!! error TS2570: Property 'method' does not exist on type 'Promise<Foo>'.
}

19 changes: 19 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromiseUnion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [missingPropertyOfPromiseUnion.ts]
interface Foo {
method();
}

interface Bar {
method();
somethingElse();
}

function f(x: Promise<Foo> | Promise<Bar>) {
x.method();
}


//// [missingPropertyOfPromiseUnion.js]
function f(x) {
x.method();
}
30 changes: 30 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromiseUnion.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/missingPropertyOfPromiseUnion.ts ===
interface Foo {
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseUnion.ts, 0, 0))

method();
>method : Symbol(Foo.method, Decl(missingPropertyOfPromiseUnion.ts, 0, 15))
}

interface Bar {
>Bar : Symbol(Bar, Decl(missingPropertyOfPromiseUnion.ts, 2, 1))

method();
>method : Symbol(Bar.method, Decl(missingPropertyOfPromiseUnion.ts, 4, 15))

somethingElse();
>somethingElse : Symbol(Bar.somethingElse, Decl(missingPropertyOfPromiseUnion.ts, 5, 13))
}

function f(x: Promise<Foo> | Promise<Bar>) {
>f : Symbol(f, Decl(missingPropertyOfPromiseUnion.ts, 7, 1))
>x : Symbol(x, Decl(missingPropertyOfPromiseUnion.ts, 9, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, --, --))
>Foo : Symbol(Foo, Decl(missingPropertyOfPromiseUnion.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, --, --))
>Bar : Symbol(Bar, Decl(missingPropertyOfPromiseUnion.ts, 2, 1))

x.method();
>x : Symbol(x, Decl(missingPropertyOfPromiseUnion.ts, 9, 11))
}

33 changes: 33 additions & 0 deletions tests/baselines/reference/missingPropertyOfPromiseUnion.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
=== tests/cases/compiler/missingPropertyOfPromiseUnion.ts ===
interface Foo {
>Foo : Foo

method();
>method : () => any
}

interface Bar {
>Bar : Bar

method();
>method : () => any

somethingElse();
>somethingElse : () => any
}

function f(x: Promise<Foo> | Promise<Bar>) {
>f : (x: Promise<Foo> | Promise<Bar>) => void
>x : Promise<Foo> | Promise<Bar>
>Promise : Promise<T>
>Foo : Foo
>Promise : Promise<T>
>Bar : Bar

x.method();
>x.method() : any
>x.method : any
>x : Promise<Foo> | Promise<Bar>
>method : any
}

3 changes: 3 additions & 0 deletions tests/cases/compiler/missingPropertyOfPromise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function f(x: Promise<string>) {
x.toLowerCase();
}
11 changes: 11 additions & 0 deletions tests/cases/compiler/missingPropertyOfPromiseIntersection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
interface Foo {
method();
}

interface Bar {
somethingElse();
}

function f(x: Promise<Foo> & Bar) {
x.method();
}
12 changes: 12 additions & 0 deletions tests/cases/compiler/missingPropertyOfPromiseUnion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
interface Foo {
method();
}

interface Bar {
method();
somethingElse();
}

function f(x: Promise<Foo> | Promise<Bar>) {
x.method();
}

0 comments on commit 49a2599

Please sign in to comment.