diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 34e5000790add..13db690aa4abe 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16616,12 +16616,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 e9bf71dd6eb49..69a90fbabf5b4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2012,7 +2012,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(); +}