From 4983e11b67af07c4d0c737249f22a51e2f614f5a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 11:04:53 -0700 Subject: [PATCH 1/9] Added test for leading underscore property name suggestions. --- .../spellingSuggestionLeadingUnderscores01.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts diff --git a/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts b/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts new file mode 100644 index 00000000000..99c9644b095 --- /dev/null +++ b/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts @@ -0,0 +1,17 @@ +// @module: commonjs +// @filename abc.ts +export declare let a: { + __foo: 10, +} + +a.___foo + +// @filename def.ts +export let b: { + __foo: number +} + +b = { + __foo: 100, +} + From 4ac9091ea14665a42cfd397113b9f04a4e8abd7c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 11:46:51 -0700 Subject: [PATCH 2/9] Accepted baselines. --- ...gSuggestionLeadingUnderscores01.errors.txt | 23 ++++++++++++++++ .../spellingSuggestionLeadingUnderscores01.js | 26 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt create mode 100644 tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js diff --git a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt new file mode 100644 index 00000000000..a265dfc1fb6 --- /dev/null +++ b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '___foo'? + + +==== tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts (1 errors) ==== + // @filename abc.ts + export declare let a: { + __foo: 10, + } + + a.___foo + ~~~~~~ +!!! error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '___foo'? + + // @filename def.ts + export let b: { + __foo: number + } + + b = { + __foo: 100, + } + + \ No newline at end of file diff --git a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js new file mode 100644 index 00000000000..fbcc3dc1cad --- /dev/null +++ b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js @@ -0,0 +1,26 @@ +//// [spellingSuggestionLeadingUnderscores01.ts] +// @filename abc.ts +export declare let a: { + __foo: 10, +} + +a.___foo + +// @filename def.ts +export let b: { + __foo: number +} + +b = { + __foo: 100, +} + + + +//// [spellingSuggestionLeadingUnderscores01.js] +"use strict"; +exports.__esModule = true; +exports.a.___foo; +exports.b = { + __foo: 100 +}; From 70ad2bdb3134139ec21c6682c42e523aa4a1784c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 12:54:35 -0700 Subject: [PATCH 3/9] Ensure that property suggestions are correctly escaped. --- src/compiler/checker.ts | 4 ++-- src/compiler/core.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6df6b1f9ce1..54388d09e7d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14676,8 +14676,8 @@ namespace ts { } } const suggestion = getSuggestionForNonexistentProperty(propNode, containingType); - if (suggestion) { - errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion); + if (suggestion !== undefined) { + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), unescapeLeadingUnderscores(suggestion)); } else { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType)); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 8cab1b41155..eae2e5ee336 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1359,7 +1359,7 @@ namespace ts { }; } - export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain; + export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: string[]): DiagnosticMessageChain; export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain { let text = getLocaleSpecificMessage(message); From 50671c374c51383d80360963f8635c5a9af97eed Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 12:55:35 -0700 Subject: [PATCH 4/9] Try to provide a spelling suggestion when object literals have excess properties. --- src/compiler/checker.ts | 21 ++++++++++++++++++--- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 54388d09e7d..d2b51867217 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9067,11 +9067,26 @@ namespace ts { else { // use the property's value declaration if the property is assigned inside the literal itself const objectLiteralDeclaration = source.symbol && firstOrUndefined(source.symbol.declarations); + let suggestion; if (prop.valueDeclaration && findAncestor(prop.valueDeclaration, d => d === objectLiteralDeclaration)) { - errorNode = prop.valueDeclaration; + const propDeclaration = prop.valueDeclaration as ObjectLiteralElementLike; + Debug.assertNode(propDeclaration, isObjectLiteralElementLike); + + errorNode = propDeclaration; + + const propNameNode = propDeclaration.name as Identifier; + Debug.assertNode(propNameNode, isIdentifier); + suggestion = getSuggestionForNonexistentProperty(propNameNode, target); + } + + if (suggestion !== undefined) { + reportError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, + symbolToString(prop), typeToString(target), unescapeLeadingUnderscores(suggestion)); + } + else { + reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, + symbolToString(prop), typeToString(target)); } - reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, - symbolToString(prop), typeToString(target)); } } return true; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 77e7f7e7b62..e7d292d57d1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1912,6 +1912,10 @@ "category": "Error", "code": 2560 }, + "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?": { + "category": "Error", + "code": 2561 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 From 8b10ea4c1d3a4376e18a70a8be7d0e0af780ceed Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 12:55:54 -0700 Subject: [PATCH 5/9] Accepted baselines. --- .../reference/nestedFreshLiteral.errors.txt | 4 ++-- .../objectLiteralExcessProperties.errors.txt | 16 ++++++++-------- ...lingSuggestionLeadingUnderscores01.errors.txt | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/nestedFreshLiteral.errors.txt b/tests/baselines/reference/nestedFreshLiteral.errors.txt index 6aff94ac0a6..d68b398449d 100644 --- a/tests/baselines/reference/nestedFreshLiteral.errors.txt +++ b/tests/baselines/reference/nestedFreshLiteral.errors.txt @@ -4,7 +4,7 @@ tests/cases/compiler/nestedFreshLiteral.ts(12,21): error TS2322: Type '{ nested: Type '{ prop: { colour: string; }; }' is not assignable to type 'NestedSelector'. Types of property 'prop' are incompatible. Type '{ colour: string; }' is not assignable to type 'CSSProps'. - Object literal may only specify known properties, and 'colour' does not exist in type 'CSSProps'. + Object literal may only specify known properties, but 'colour' does not exist in type 'CSSProps'. Did you mean to write 'color'? ==== tests/cases/compiler/nestedFreshLiteral.ts (1 errors) ==== @@ -27,5 +27,5 @@ tests/cases/compiler/nestedFreshLiteral.ts(12,21): error TS2322: Type '{ nested: !!! error TS2322: Type '{ prop: { colour: string; }; }' is not assignable to type 'NestedSelector'. !!! error TS2322: Types of property 'prop' are incompatible. !!! error TS2322: Type '{ colour: string; }' is not assignable to type 'CSSProps'. -!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'CSSProps'. +!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'CSSProps'. Did you mean to write 'color'? } \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralExcessProperties.errors.txt b/tests/baselines/reference/objectLiteralExcessProperties.errors.txt index 98f2e30287c..0c5909dc4ed 100644 --- a/tests/baselines/reference/objectLiteralExcessProperties.errors.txt +++ b/tests/baselines/reference/objectLiteralExcessProperties.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(9,18): error TS2322: Type '{ forword: string; }' is not assignable to type 'Book'. - Object literal may only specify known properties, and 'forword' does not exist in type 'Book'. + Object literal may only specify known properties, but 'forword' does not exist in type 'Book'. Did you mean to write 'foreword'? tests/cases/compiler/objectLiteralExcessProperties.ts(11,27): error TS2322: Type '{ foreward: string; }' is not assignable to type 'string | Book'. Object literal may only specify known properties, and 'foreward' does not exist in type 'string | Book'. tests/cases/compiler/objectLiteralExcessProperties.ts(13,53): error TS2322: Type '({ foreword: string; } | { forwards: string; })[]' is not assignable to type 'Book | Book[]'. @@ -8,9 +8,9 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(13,53): error TS2322: Type Type '{ forwards: string; }' is not assignable to type 'Book'. Object literal may only specify known properties, and 'forwards' does not exist in type 'Book'. tests/cases/compiler/objectLiteralExcessProperties.ts(15,42): error TS2322: Type '{ foreword: string; colour: string; }' is not assignable to type 'Book & Cover'. - Object literal may only specify known properties, and 'colour' does not exist in type 'Book & Cover'. + Object literal may only specify known properties, but 'colour' does not exist in type 'Book & Cover'. Did you mean to write 'color'? tests/cases/compiler/objectLiteralExcessProperties.ts(17,26): error TS2322: Type '{ foreward: string; color: string; }' is not assignable to type 'Book & Cover'. - Object literal may only specify known properties, and 'foreward' does not exist in type 'Book & Cover'. + Object literal may only specify known properties, but 'foreward' does not exist in type 'Book & Cover'. Did you mean to write 'foreword'? tests/cases/compiler/objectLiteralExcessProperties.ts(19,57): error TS2322: Type '{ foreword: string; color: string; price: number; }' is not assignable to type 'Book & Cover'. Object literal may only specify known properties, and 'price' does not exist in type 'Book & Cover'. tests/cases/compiler/objectLiteralExcessProperties.ts(21,43): error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'Book & number'. @@ -22,7 +22,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(25,27): error TS2322: Type tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type '{ 0: { colour: string; }; }' is not assignable to type 'Indexed'. Property '0' is incompatible with index signature. Type '{ colour: string; }' is not assignable to type 'Cover'. - Object literal may only specify known properties, and 'colour' does not exist in type 'Cover'. + Object literal may only specify known properties, but 'colour' does not exist in type 'Cover'. Did you mean to write 'color'? ==== tests/cases/compiler/objectLiteralExcessProperties.ts (10 errors) ==== @@ -37,7 +37,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type var b1: Book = { forword: "oops" }; ~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ forword: string; }' is not assignable to type 'Book'. -!!! error TS2322: Object literal may only specify known properties, and 'forword' does not exist in type 'Book'. +!!! error TS2322: Object literal may only specify known properties, but 'forword' does not exist in type 'Book'. Did you mean to write 'foreword'? var b2: Book | string = { foreward: "nope" }; ~~~~~~~~~~~~~~~~ @@ -55,12 +55,12 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type var b4: Book & Cover = { foreword: "hi", colour: "blue" }; ~~~~~~~~~~~~~~ !!! error TS2322: Type '{ foreword: string; colour: string; }' is not assignable to type 'Book & Cover'. -!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'Book & Cover'. +!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'Book & Cover'. Did you mean to write 'color'? var b5: Book & Cover = { foreward: "hi", color: "blue" }; ~~~~~~~~~~~~~~ !!! error TS2322: Type '{ foreward: string; color: string; }' is not assignable to type 'Book & Cover'. -!!! error TS2322: Object literal may only specify known properties, and 'foreward' does not exist in type 'Book & Cover'. +!!! error TS2322: Object literal may only specify known properties, but 'foreward' does not exist in type 'Book & Cover'. Did you mean to write 'foreword'? var b6: Book & Cover = { foreword: "hi", color: "blue", price: 10.99 }; ~~~~~~~~~~~~ @@ -93,5 +93,5 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type !!! error TS2322: Type '{ 0: { colour: string; }; }' is not assignable to type 'Indexed'. !!! error TS2322: Property '0' is incompatible with index signature. !!! error TS2322: Type '{ colour: string; }' is not assignable to type 'Cover'. -!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'Cover'. +!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'Cover'. Did you mean to write 'color'? \ No newline at end of file diff --git a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt index a265dfc1fb6..af0a647f87e 100644 --- a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt +++ b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '___foo'? +tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '__foo'? ==== tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts (1 errors) ==== @@ -9,7 +9,7 @@ tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS255 a.___foo ~~~~~~ -!!! error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '___foo'? +!!! error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '__foo'? // @filename def.ts export let b: { From 7cc6bfc98572c2812088dddffaede3df3d36a904 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Aug 2017 15:58:31 -0700 Subject: [PATCH 6/9] Only give suggestions when the name is an identifier. --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d2b51867217..d128eb29d95 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9074,9 +9074,9 @@ namespace ts { errorNode = propDeclaration; - const propNameNode = propDeclaration.name as Identifier; - Debug.assertNode(propNameNode, isIdentifier); - suggestion = getSuggestionForNonexistentProperty(propNameNode, target); + if (isIdentifier(propDeclaration.name)) { + suggestion = getSuggestionForNonexistentProperty(propDeclaration.name, target); + } } if (suggestion !== undefined) { From 7739a1cea01236ced5990d77bec2d6e4d40963e4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 19 Aug 2017 00:03:35 -0700 Subject: [PATCH 7/9] Actually misspell the property name. --- tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts b/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts index 99c9644b095..cf60136f5eb 100644 --- a/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts +++ b/tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts @@ -12,6 +12,6 @@ export let b: { } b = { - __foo: 100, + ___foo: 100, } From a1ad389d247d0e5960fd5616867b7d03fb6d0564 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 19 Aug 2017 00:08:25 -0700 Subject: [PATCH 8/9] Accepted baselines. --- .../spellingSuggestionLeadingUnderscores01.errors.txt | 9 +++++++-- .../reference/spellingSuggestionLeadingUnderscores01.js | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt index af0a647f87e..39a4901da98 100644 --- a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt +++ b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.errors.txt @@ -1,7 +1,9 @@ tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '__foo'? +tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(14,5): error TS2322: Type '{ ___foo: number; }' is not assignable to type '{ __foo: number; }'. + Object literal may only specify known properties, but '___foo' does not exist in type '{ __foo: number; }'. Did you mean to write '__foo'? -==== tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts (1 errors) ==== +==== tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts (2 errors) ==== // @filename abc.ts export declare let a: { __foo: 10, @@ -17,7 +19,10 @@ tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS255 } b = { - __foo: 100, + ___foo: 100, + ~~~~~~~~~~~ +!!! error TS2322: Type '{ ___foo: number; }' is not assignable to type '{ __foo: number; }'. +!!! error TS2322: Object literal may only specify known properties, but '___foo' does not exist in type '{ __foo: number; }'. Did you mean to write '__foo'? } \ No newline at end of file diff --git a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js index fbcc3dc1cad..6a84749b153 100644 --- a/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js +++ b/tests/baselines/reference/spellingSuggestionLeadingUnderscores01.js @@ -12,7 +12,7 @@ export let b: { } b = { - __foo: 100, + ___foo: 100, } @@ -22,5 +22,5 @@ b = { exports.__esModule = true; exports.a.___foo; exports.b = { - __foo: 100 + ___foo: 100 }; From f8e8afec1b45b5d7d8ae6ba95ecbea37fcb7936b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 22 Aug 2017 21:18:25 -0700 Subject: [PATCH 9/9] Accepted baselines. --- .../reference/baseExpressionTypeParameters.errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/baseExpressionTypeParameters.errors.txt b/tests/baselines/reference/baseExpressionTypeParameters.errors.txt index 4fa8f2f6d3d..cb259e49dd2 100644 --- a/tests/baselines/reference/baseExpressionTypeParameters.errors.txt +++ b/tests/baselines/reference/baseExpressionTypeParameters.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2561: Base class expressions cannot reference class type parameters. +tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2562: Base class expressions cannot reference class type parameters. ==== tests/cases/compiler/baseExpressionTypeParameters.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2561: Base class Gen extends base() {} // Error, T not in scope ~ -!!! error TS2561: Base class expressions cannot reference class type parameters. +!!! error TS2562: Base class expressions cannot reference class type parameters. class Spec extends Gen {} Spec.prop; \ No newline at end of file