From 134b3411ee74146beca65f77cb08ce22a54a68e1 Mon Sep 17 00:00:00 2001 From: Alex Khomchenko Date: Sun, 1 Apr 2018 18:11:06 +0200 Subject: [PATCH] Fix issue #22923 --- src/compiler/checker.ts | 14 ++++++++++---- src/compiler/diagnosticMessages.json | 5 ++++- ...stentPropertyAvailableOnPromisedType.errors.txt | 10 ++++++++++ .../nonexistentPropertyAvailableOnPromisedType.js | 10 ++++++++++ ...existentPropertyAvailableOnPromisedType.symbols | 10 ++++++++++ ...onexistentPropertyAvailableOnPromisedType.types | 13 +++++++++++++ .../nonexistentPropertyOnUnion.errors.txt | 12 ++++++++++++ .../reference/nonexistentPropertyOnUnion.js | 10 ++++++++++ .../reference/nonexistentPropertyOnUnion.symbols | 10 ++++++++++ .../reference/nonexistentPropertyOnUnion.types | 13 +++++++++++++ ...entPropertyUnavailableOnPromisedType.errors.txt | 10 ++++++++++ ...nonexistentPropertyUnavailableOnPromisedType.js | 10 ++++++++++ ...istentPropertyUnavailableOnPromisedType.symbols | 10 ++++++++++ ...existentPropertyUnavailableOnPromisedType.types | 13 +++++++++++++ .../nonexistentPropertyAvailableOnPromisedType.ts | 3 +++ tests/cases/compiler/nonexistentPropertyOnUnion.ts | 3 +++ ...nonexistentPropertyUnavailableOnPromisedType.ts | 3 +++ 17 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.errors.txt create mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.js create mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.symbols create mode 100644 tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.types create mode 100644 tests/baselines/reference/nonexistentPropertyOnUnion.errors.txt create mode 100644 tests/baselines/reference/nonexistentPropertyOnUnion.js create mode 100644 tests/baselines/reference/nonexistentPropertyOnUnion.symbols create mode 100644 tests/baselines/reference/nonexistentPropertyOnUnion.types create mode 100644 tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.errors.txt create mode 100644 tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.js create mode 100644 tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.symbols create mode 100644 tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.types create mode 100644 tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts create mode 100644 tests/cases/compiler/nonexistentPropertyOnUnion.ts create mode 100644 tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 307680d941ef1..8f99e21efb9f1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16405,12 +16405,18 @@ namespace ts { } } } - const suggestion = getSuggestionForNonexistentProperty(propNode, containingType); - if (suggestion !== undefined) { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion); + const promisedType = getPromisedTypeOfPromise(containingType); + if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) { + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await, declarationNameToString(propNode), typeToString(containingType)); } else { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); + const suggestion = getSuggestionForNonexistentProperty(propNode, containingType); + 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 { + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); + } } diagnostics.add(createDiagnosticForNodeFromMessageChain(propNode, errorInfo)); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index bbc00e6fbc621..12216c16ce67e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2000,7 +2000,10 @@ "category": "Error", "code": 2569 }, - + "Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?": { + "category": "Error", + "code": 2570 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 diff --git a/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.errors.txt b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.errors.txt new file mode 100644 index 0000000000000..e898ec5e18f0b --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts(2,7): error TS2570: Property 'toLowerCase' does not exist on type 'Promise'. Did you forget to use 'await'? + + +==== tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts (1 errors) ==== + function f(x: Promise) { + x.toLowerCase(); + ~~~~~~~~~~~ +!!! error TS2570: Property 'toLowerCase' does not exist on type 'Promise'. Did you forget to use 'await'? + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.js b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.js new file mode 100644 index 0000000000000..f07ed7b9ddfdf --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.js @@ -0,0 +1,10 @@ +//// [nonexistentPropertyAvailableOnPromisedType.ts] +function f(x: Promise) { + x.toLowerCase(); +} + + +//// [nonexistentPropertyAvailableOnPromisedType.js] +function f(x) { + x.toLowerCase(); +} diff --git a/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.symbols b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.symbols new file mode 100644 index 0000000000000..6e8de9ce43dac --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts === +function f(x: Promise) { +>f : Symbol(f, Decl(nonexistentPropertyAvailableOnPromisedType.ts, 0, 0)) +>x : Symbol(x, Decl(nonexistentPropertyAvailableOnPromisedType.ts, 0, 11)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) + + x.toLowerCase(); +>x : Symbol(x, Decl(nonexistentPropertyAvailableOnPromisedType.ts, 0, 11)) +} + diff --git a/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.types b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.types new file mode 100644 index 0000000000000..6d040bf583e7d --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyAvailableOnPromisedType.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts === +function f(x: Promise) { +>f : (x: Promise) => void +>x : Promise +>Promise : Promise + + x.toLowerCase(); +>x.toLowerCase() : any +>x.toLowerCase : any +>x : Promise +>toLowerCase : any +} + diff --git a/tests/baselines/reference/nonexistentPropertyOnUnion.errors.txt b/tests/baselines/reference/nonexistentPropertyOnUnion.errors.txt new file mode 100644 index 0000000000000..43a3de81843fc --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyOnUnion.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/nonexistentPropertyOnUnion.ts(2,7): error TS2339: Property 'toLowerCase' does not exist on type 'string | Promise'. + Property 'toLowerCase' does not exist on type 'Promise'. + + +==== tests/cases/compiler/nonexistentPropertyOnUnion.ts (1 errors) ==== + function f(x: string | Promise) { + x.toLowerCase(); + ~~~~~~~~~~~ +!!! error TS2339: Property 'toLowerCase' does not exist on type 'string | Promise'. +!!! error TS2339: Property 'toLowerCase' does not exist on type 'Promise'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonexistentPropertyOnUnion.js b/tests/baselines/reference/nonexistentPropertyOnUnion.js new file mode 100644 index 0000000000000..1656f3386d824 --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyOnUnion.js @@ -0,0 +1,10 @@ +//// [nonexistentPropertyOnUnion.ts] +function f(x: string | Promise) { + x.toLowerCase(); +} + + +//// [nonexistentPropertyOnUnion.js] +function f(x) { + x.toLowerCase(); +} diff --git a/tests/baselines/reference/nonexistentPropertyOnUnion.symbols b/tests/baselines/reference/nonexistentPropertyOnUnion.symbols new file mode 100644 index 0000000000000..1b86585994984 --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyOnUnion.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/nonexistentPropertyOnUnion.ts === +function f(x: string | Promise) { +>f : Symbol(f, Decl(nonexistentPropertyOnUnion.ts, 0, 0)) +>x : Symbol(x, Decl(nonexistentPropertyOnUnion.ts, 0, 11)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) + + x.toLowerCase(); +>x : Symbol(x, Decl(nonexistentPropertyOnUnion.ts, 0, 11)) +} + diff --git a/tests/baselines/reference/nonexistentPropertyOnUnion.types b/tests/baselines/reference/nonexistentPropertyOnUnion.types new file mode 100644 index 0000000000000..61bfdb4349456 --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyOnUnion.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/nonexistentPropertyOnUnion.ts === +function f(x: string | Promise) { +>f : (x: string | Promise) => void +>x : string | Promise +>Promise : Promise + + x.toLowerCase(); +>x.toLowerCase() : any +>x.toLowerCase : any +>x : string | Promise +>toLowerCase : any +} + diff --git a/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.errors.txt b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.errors.txt new file mode 100644 index 0000000000000..983bcfad24551 --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts(2,7): error TS2339: Property 'toLowerCase' does not exist on type 'Promise'. + + +==== tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts (1 errors) ==== + function f(x: Promise) { + x.toLowerCase(); + ~~~~~~~~~~~ +!!! error TS2339: Property 'toLowerCase' does not exist on type 'Promise'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.js b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.js new file mode 100644 index 0000000000000..2983bc1b6b630 --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.js @@ -0,0 +1,10 @@ +//// [nonexistentPropertyUnavailableOnPromisedType.ts] +function f(x: Promise) { + x.toLowerCase(); +} + + +//// [nonexistentPropertyUnavailableOnPromisedType.js] +function f(x) { + x.toLowerCase(); +} diff --git a/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.symbols b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.symbols new file mode 100644 index 0000000000000..3754a5ff13209 --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts === +function f(x: Promise) { +>f : Symbol(f, Decl(nonexistentPropertyUnavailableOnPromisedType.ts, 0, 0)) +>x : Symbol(x, Decl(nonexistentPropertyUnavailableOnPromisedType.ts, 0, 11)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) + + x.toLowerCase(); +>x : Symbol(x, Decl(nonexistentPropertyUnavailableOnPromisedType.ts, 0, 11)) +} + diff --git a/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.types b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.types new file mode 100644 index 0000000000000..d5ad7490ea62e --- /dev/null +++ b/tests/baselines/reference/nonexistentPropertyUnavailableOnPromisedType.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts === +function f(x: Promise) { +>f : (x: Promise) => void +>x : Promise +>Promise : Promise + + x.toLowerCase(); +>x.toLowerCase() : any +>x.toLowerCase : any +>x : Promise +>toLowerCase : any +} + diff --git a/tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts b/tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts new file mode 100644 index 0000000000000..476f4ac563617 --- /dev/null +++ b/tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts @@ -0,0 +1,3 @@ +function f(x: Promise) { + x.toLowerCase(); +} diff --git a/tests/cases/compiler/nonexistentPropertyOnUnion.ts b/tests/cases/compiler/nonexistentPropertyOnUnion.ts new file mode 100644 index 0000000000000..16e8acf17e31a --- /dev/null +++ b/tests/cases/compiler/nonexistentPropertyOnUnion.ts @@ -0,0 +1,3 @@ +function f(x: string | Promise) { + x.toLowerCase(); +} diff --git a/tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts b/tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts new file mode 100644 index 0000000000000..5e6a5ca23dc7a --- /dev/null +++ b/tests/cases/compiler/nonexistentPropertyUnavailableOnPromisedType.ts @@ -0,0 +1,3 @@ +function f(x: Promise) { + x.toLowerCase(); +}