Skip to content
Merged
25 changes: 20 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9077,11 +9077,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;

if (isIdentifier(propDeclaration.name)) {
suggestion = getSuggestionForNonexistentProperty(propDeclaration.name, 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;
Expand Down Expand Up @@ -14686,8 +14701,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));
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 5 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1912,10 +1912,14 @@
"category": "Error",
"code": 2560
},
"Base class expressions cannot reference class type parameters.": {
"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
},
"Base class expressions cannot reference class type parameters.": {
"category": "Error",
"code": 2562
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
Expand Down
Original file line number Diff line number Diff line change
@@ -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) ====
Expand All @@ -13,7 +13,7 @@ tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2561: Base

class Gen<T> extends base<T>() {} // 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<string> {}

<string>Spec.prop;
4 changes: 2 additions & 2 deletions tests/baselines/reference/nestedFreshLiteral.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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) ====
Expand All @@ -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'?
}
Original file line number Diff line number Diff line change
@@ -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[]'.
Expand All @@ -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'.
Expand All @@ -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) ====
Expand All @@ -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" };
~~~~~~~~~~~~~~~~
Expand All @@ -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 };
~~~~~~~~~~~~
Expand Down Expand Up @@ -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'?

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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 (2 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,
~~~~~~~~~~~
!!! 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'?
}


Original file line number Diff line number Diff line change
@@ -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
};
17 changes: 17 additions & 0 deletions tests/cases/compiler/spellingSuggestionLeadingUnderscores01.ts
Original file line number Diff line number Diff line change
@@ -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,
}