Skip to content

Commit a52030d

Browse files
Merge pull request #17907 from Microsoft/excessPropCorrection
Provide spelling suggestions for excess property errors
2 parents 356f54a + f8e8afe commit a52030d

9 files changed

+109
-19
lines changed

src/compiler/checker.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9083,11 +9083,26 @@ namespace ts {
90839083
else {
90849084
// use the property's value declaration if the property is assigned inside the literal itself
90859085
const objectLiteralDeclaration = source.symbol && firstOrUndefined(source.symbol.declarations);
9086+
let suggestion;
90869087
if (prop.valueDeclaration && findAncestor(prop.valueDeclaration, d => d === objectLiteralDeclaration)) {
9087-
errorNode = prop.valueDeclaration;
9088+
const propDeclaration = prop.valueDeclaration as ObjectLiteralElementLike;
9089+
Debug.assertNode(propDeclaration, isObjectLiteralElementLike);
9090+
9091+
errorNode = propDeclaration;
9092+
9093+
if (isIdentifier(propDeclaration.name)) {
9094+
suggestion = getSuggestionForNonexistentProperty(propDeclaration.name, target);
9095+
}
9096+
}
9097+
9098+
if (suggestion !== undefined) {
9099+
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2,
9100+
symbolToString(prop), typeToString(target), unescapeLeadingUnderscores(suggestion));
9101+
}
9102+
else {
9103+
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
9104+
symbolToString(prop), typeToString(target));
90889105
}
9089-
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
9090-
symbolToString(prop), typeToString(target));
90919106
}
90929107
}
90939108
return true;
@@ -14739,8 +14754,8 @@ namespace ts {
1473914754
}
1474014755
}
1474114756
const suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
14742-
if (suggestion) {
14743-
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
14757+
if (suggestion !== undefined) {
14758+
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), unescapeLeadingUnderscores(suggestion));
1474414759
}
1474514760
else {
1474614761
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));

src/compiler/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ namespace ts {
13591359
};
13601360
}
13611361

1362-
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
1362+
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: string[]): DiagnosticMessageChain;
13631363
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
13641364
let text = getLocaleSpecificMessage(message);
13651365

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1912,10 +1912,14 @@
19121912
"category": "Error",
19131913
"code": 2560
19141914
},
1915-
"Base class expressions cannot reference class type parameters.": {
1915+
"Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?": {
19161916
"category": "Error",
19171917
"code": 2561
19181918
},
1919+
"Base class expressions cannot reference class type parameters.": {
1920+
"category": "Error",
1921+
"code": 2562
1922+
},
19191923
"JSX element attributes type '{0}' may not be a union type.": {
19201924
"category": "Error",
19211925
"code": 2600

tests/baselines/reference/baseExpressionTypeParameters.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2561: Base class expressions cannot reference class type parameters.
1+
tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2562: Base class expressions cannot reference class type parameters.
22

33

44
==== tests/cases/compiler/baseExpressionTypeParameters.ts (1 errors) ====
@@ -13,7 +13,7 @@ tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2561: Base
1313

1414
class Gen<T> extends base<T>() {} // Error, T not in scope
1515
~
16-
!!! error TS2561: Base class expressions cannot reference class type parameters.
16+
!!! error TS2562: Base class expressions cannot reference class type parameters.
1717
class Spec extends Gen<string> {}
1818

1919
<string>Spec.prop;

tests/baselines/reference/nestedFreshLiteral.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ tests/cases/compiler/nestedFreshLiteral.ts(12,21): error TS2322: Type '{ nested:
44
Type '{ prop: { colour: string; }; }' is not assignable to type 'NestedSelector'.
55
Types of property 'prop' are incompatible.
66
Type '{ colour: string; }' is not assignable to type 'CSSProps'.
7-
Object literal may only specify known properties, and 'colour' does not exist in type 'CSSProps'.
7+
Object literal may only specify known properties, but 'colour' does not exist in type 'CSSProps'. Did you mean to write 'color'?
88

99

1010
==== tests/cases/compiler/nestedFreshLiteral.ts (1 errors) ====
@@ -27,5 +27,5 @@ tests/cases/compiler/nestedFreshLiteral.ts(12,21): error TS2322: Type '{ nested:
2727
!!! error TS2322: Type '{ prop: { colour: string; }; }' is not assignable to type 'NestedSelector'.
2828
!!! error TS2322: Types of property 'prop' are incompatible.
2929
!!! error TS2322: Type '{ colour: string; }' is not assignable to type 'CSSProps'.
30-
!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'CSSProps'.
30+
!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'CSSProps'. Did you mean to write 'color'?
3131
}

tests/baselines/reference/objectLiteralExcessProperties.errors.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/compiler/objectLiteralExcessProperties.ts(9,18): error TS2322: Type '{ forword: string; }' is not assignable to type 'Book'.
2-
Object literal may only specify known properties, and 'forword' does not exist in type 'Book'.
2+
Object literal may only specify known properties, but 'forword' does not exist in type 'Book'. Did you mean to write 'foreword'?
33
tests/cases/compiler/objectLiteralExcessProperties.ts(11,27): error TS2322: Type '{ foreward: string; }' is not assignable to type 'string | Book'.
44
Object literal may only specify known properties, and 'foreward' does not exist in type 'string | Book'.
55
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
88
Type '{ forwards: string; }' is not assignable to type 'Book'.
99
Object literal may only specify known properties, and 'forwards' does not exist in type 'Book'.
1010
tests/cases/compiler/objectLiteralExcessProperties.ts(15,42): error TS2322: Type '{ foreword: string; colour: string; }' is not assignable to type 'Book & Cover'.
11-
Object literal may only specify known properties, and 'colour' does not exist in type 'Book & Cover'.
11+
Object literal may only specify known properties, but 'colour' does not exist in type 'Book & Cover'. Did you mean to write 'color'?
1212
tests/cases/compiler/objectLiteralExcessProperties.ts(17,26): error TS2322: Type '{ foreward: string; color: string; }' is not assignable to type 'Book & Cover'.
13-
Object literal may only specify known properties, and 'foreward' does not exist in type 'Book & Cover'.
13+
Object literal may only specify known properties, but 'foreward' does not exist in type 'Book & Cover'. Did you mean to write 'foreword'?
1414
tests/cases/compiler/objectLiteralExcessProperties.ts(19,57): error TS2322: Type '{ foreword: string; color: string; price: number; }' is not assignable to type 'Book & Cover'.
1515
Object literal may only specify known properties, and 'price' does not exist in type 'Book & Cover'.
1616
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
2222
tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type '{ 0: { colour: string; }; }' is not assignable to type 'Indexed'.
2323
Property '0' is incompatible with index signature.
2424
Type '{ colour: string; }' is not assignable to type 'Cover'.
25-
Object literal may only specify known properties, and 'colour' does not exist in type 'Cover'.
25+
Object literal may only specify known properties, but 'colour' does not exist in type 'Cover'. Did you mean to write 'color'?
2626

2727

2828
==== tests/cases/compiler/objectLiteralExcessProperties.ts (10 errors) ====
@@ -37,7 +37,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type
3737
var b1: Book = { forword: "oops" };
3838
~~~~~~~~~~~~~~~
3939
!!! error TS2322: Type '{ forword: string; }' is not assignable to type 'Book'.
40-
!!! error TS2322: Object literal may only specify known properties, and 'forword' does not exist in type 'Book'.
40+
!!! error TS2322: Object literal may only specify known properties, but 'forword' does not exist in type 'Book'. Did you mean to write 'foreword'?
4141

4242
var b2: Book | string = { foreward: "nope" };
4343
~~~~~~~~~~~~~~~~
@@ -55,12 +55,12 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type
5555
var b4: Book & Cover = { foreword: "hi", colour: "blue" };
5656
~~~~~~~~~~~~~~
5757
!!! error TS2322: Type '{ foreword: string; colour: string; }' is not assignable to type 'Book & Cover'.
58-
!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'Book & Cover'.
58+
!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'Book & Cover'. Did you mean to write 'color'?
5959

6060
var b5: Book & Cover = { foreward: "hi", color: "blue" };
6161
~~~~~~~~~~~~~~
6262
!!! error TS2322: Type '{ foreward: string; color: string; }' is not assignable to type 'Book & Cover'.
63-
!!! error TS2322: Object literal may only specify known properties, and 'foreward' does not exist in type 'Book & Cover'.
63+
!!! error TS2322: Object literal may only specify known properties, but 'foreward' does not exist in type 'Book & Cover'. Did you mean to write 'foreword'?
6464

6565
var b6: Book & Cover = { foreword: "hi", color: "blue", price: 10.99 };
6666
~~~~~~~~~~~~
@@ -93,5 +93,5 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type
9393
!!! error TS2322: Type '{ 0: { colour: string; }; }' is not assignable to type 'Indexed'.
9494
!!! error TS2322: Property '0' is incompatible with index signature.
9595
!!! error TS2322: Type '{ colour: string; }' is not assignable to type 'Cover'.
96-
!!! error TS2322: Object literal may only specify known properties, and 'colour' does not exist in type 'Cover'.
96+
!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'Cover'. Did you mean to write 'color'?
9797

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(6,3): error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '__foo'?
2+
tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts(14,5): error TS2322: Type '{ ___foo: number; }' is not assignable to type '{ __foo: number; }'.
3+
Object literal may only specify known properties, but '___foo' does not exist in type '{ __foo: number; }'. Did you mean to write '__foo'?
4+
5+
6+
==== tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts (2 errors) ====
7+
// @filename abc.ts
8+
export declare let a: {
9+
__foo: 10,
10+
}
11+
12+
a.___foo
13+
~~~~~~
14+
!!! error TS2551: Property '___foo' does not exist on type '{ __foo: 10; }'. Did you mean '__foo'?
15+
16+
// @filename def.ts
17+
export let b: {
18+
__foo: number
19+
}
20+
21+
b = {
22+
___foo: 100,
23+
~~~~~~~~~~~
24+
!!! error TS2322: Type '{ ___foo: number; }' is not assignable to type '{ __foo: number; }'.
25+
!!! error TS2322: Object literal may only specify known properties, but '___foo' does not exist in type '{ __foo: number; }'. Did you mean to write '__foo'?
26+
}
27+
28+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [spellingSuggestionLeadingUnderscores01.ts]
2+
// @filename abc.ts
3+
export declare let a: {
4+
__foo: 10,
5+
}
6+
7+
a.___foo
8+
9+
// @filename def.ts
10+
export let b: {
11+
__foo: number
12+
}
13+
14+
b = {
15+
___foo: 100,
16+
}
17+
18+
19+
20+
//// [spellingSuggestionLeadingUnderscores01.js]
21+
"use strict";
22+
exports.__esModule = true;
23+
exports.a.___foo;
24+
exports.b = {
25+
___foo: 100
26+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @module: commonjs
2+
// @filename abc.ts
3+
export declare let a: {
4+
__foo: 10,
5+
}
6+
7+
a.___foo
8+
9+
// @filename def.ts
10+
export let b: {
11+
__foo: number
12+
}
13+
14+
b = {
15+
___foo: 100,
16+
}
17+

0 commit comments

Comments
 (0)