Merge pull request #38754 from a-tarasyuk/feat/25259

feat(25259): Better error report for equals instead of colon in object literals
This commit is contained in:
Daniel Rosenwasser
2020-06-30 01:56:26 -07:00
committed by GitHub
12 changed files with 129 additions and 19 deletions

View File

@@ -23893,7 +23893,10 @@ namespace ts {
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ||
isObjectLiteralMethod(memberDecl)) {
let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) :
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(memberDecl.name, checkMode) :
// avoid resolving the left side of the ShorthandPropertyAssignment outside of the destructuring
// for error recovery purposes. For example, if a user wrote `{ a = 100 }` instead of `{ a: 100 }`.
// we don't want to say "could not find 'a'".
memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(!inDestructuringPattern && memberDecl.objectAssignmentInitializer ? memberDecl.objectAssignmentInitializer : memberDecl.name, checkMode) :
checkObjectLiteralMethod(memberDecl, checkMode);
if (isInJavascript) {
const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
@@ -38223,7 +38226,7 @@ namespace ts {
if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && prop.objectAssignmentInitializer) {
// having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
// outside of destructuring it is a syntax error
return grammarErrorOnNode(prop.equalsToken!, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
return grammarErrorOnNode(prop.equalsToken!, Diagnostics.Did_you_mean_to_use_a_Colon_When_following_property_names_in_an_object_literal_implies_a_destructuring_assignment);
}
if (name.kind === SyntaxKind.PrivateIdentifier) {

View File

@@ -880,7 +880,7 @@
"category": "Error",
"code": 1308
},
"'=' can only be used in an object literal property inside a destructuring assignment.": {
"Did you mean to use a ':'? When following property names in an object literal, '=' implies a destructuring assignment.": {
"category": "Error",
"code": 1312
},
@@ -5819,6 +5819,10 @@
"category": "Message",
"code": 95137
},
"Switch each misused '{0}' to '{1}'": {
"category": "Message",
"code": 95138
},
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
"category": "Error",

View File

@@ -0,0 +1,28 @@
/* @internal */
namespace ts.codefix {
const fixId = "fixPropertyAssignment";
const errorCodes = [
Diagnostics.Did_you_mean_to_use_a_Colon_When_following_property_names_in_an_object_literal_implies_a_destructuring_assignment.code
];
registerCodeFix({
errorCodes,
fixIds: [fixId],
getCodeActions(context) {
const { sourceFile, span } = context;
const property = getProperty(sourceFile, span.start);
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, property));
return [createCodeFixAction(fixId, changes, [Diagnostics.Change_0_to_1, "=", ":"], fixId, [Diagnostics.Switch_each_misused_0_to_1, "=", ":"])];
},
getAllCodeActions: context =>
codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, getProperty(diag.file, diag.start)))
});
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: ShorthandPropertyAssignment): void {
changes.replaceNode(sourceFile, node, factory.createPropertyAssignment(node.name, node.objectAssignmentInitializer as Expression));
}
function getProperty(sourceFile: SourceFile, pos: number): ShorthandPropertyAssignment {
return cast(getTokenAtPosition(sourceFile, pos).parent, isShorthandPropertyAssignment);
}
}

View File

@@ -76,6 +76,7 @@
"codefixes/fixEnableExperimentalDecorators.ts",
"codefixes/fixEnableJsxFlag.ts",
"codefixes/fixModuleAndTargetOptions.ts",
"codefixes/fixPropertyAssignment.ts",
"codefixes/fixExtendsInterfaceBecomesImplements.ts",
"codefixes/fixForgottenThisPropertyAccess.ts",
"codefixes/fixInvalidJsxCharacters.ts",

View File

@@ -11,11 +11,10 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(85,19): erro
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(85,26): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(111,12): error TS18004: No value exists in scope for the shorthand property 's'. Either declare one or provide an initializer.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(111,14): error TS1312: '=' can only be used in an object literal property inside a destructuring assignment.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(111,14): error TS1312: Did you mean to use a ':'? When following property names in an object literal, '=' implies a destructuring assignment.
==== tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts (13 errors) ====
==== tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts (12 errors) ====
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
@@ -153,10 +152,8 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(111,14): err
(function() {
let a = { s = 5 };
~
!!! error TS18004: No value exists in scope for the shorthand property 's'. Either declare one or provide an initializer.
~
!!! error TS1312: '=' can only be used in an object literal property inside a destructuring assignment.
!!! error TS1312: Did you mean to use a ':'? When following property names in an object literal, '=' implies a destructuring assignment.
});
function foo({a = 4, b = { x: 5 }}) {

View File

@@ -417,8 +417,8 @@
>function() { let a = { s = 5 };} : () => void
let a = { s = 5 };
>a : { s: any; }
>{ s = 5 } : { s: any; }
>a : { s: number; }
>{ s = 5 } : { s: number; }
>s : any
>5 : 5

View File

@@ -11,11 +11,10 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(85,19):
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(85,26): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(111,12): error TS18004: No value exists in scope for the shorthand property 's'. Either declare one or provide an initializer.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(111,14): error TS1312: '=' can only be used in an object literal property inside a destructuring assignment.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(111,14): error TS1312: Did you mean to use a ':'? When following property names in an object literal, '=' implies a destructuring assignment.
==== tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts (13 errors) ====
==== tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts (12 errors) ====
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
@@ -153,10 +152,8 @@ tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(111,14):
(function() {
let a = { s = 5 };
~
!!! error TS18004: No value exists in scope for the shorthand property 's'. Either declare one or provide an initializer.
~
!!! error TS1312: '=' can only be used in an object literal property inside a destructuring assignment.
!!! error TS1312: Did you mean to use a ':'? When following property names in an object literal, '=' implies a destructuring assignment.
});
function foo({a = 4, b = { x: 5 }}) {

View File

@@ -417,8 +417,8 @@
>function() { let a = { s = 5 };} : () => void
let a = { s = 5 };
>a : { s: any; }
>{ s = 5 } : { s: any; }
>a : { s: number; }
>{ s = 5 } : { s: number; }
>s : any
>5 : 5

View File

@@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
////const a = {
//// x/**/= 1
////}
verify.codeFix({
description: [ts.Diagnostics.Change_0_to_1.message, "=", ":"],
index: 0,
newFileContent:
`const a = {
x: 1
}`,
});

View File

@@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
////const a = {
//// x /**/= 1
////}
verify.codeFix({
description: [ts.Diagnostics.Change_0_to_1.message, "=", ":"],
index: 0,
newFileContent:
`const a = {
x: 1
}`,
});

View File

@@ -0,0 +1,18 @@
/// <reference path='fourslash.ts'/>
////const a = {
//// x: 1,
//// y /**/= 1,
//// z: 1
////}
verify.codeFix({
description: [ts.Diagnostics.Change_0_to_1.message, "=", ":"],
index: 0,
newFileContent:
`const a = {
x: 1,
y: 1,
z: 1
}`,
});

View File

@@ -0,0 +1,34 @@
/// <reference path='fourslash.ts'/>
////const a = {
//// x: 1,
//// y = 1,
//// z: 1
////}
////const b = {
//// x = 1,
//// y: 1
////}
////const c = {
//// x: 1,
//// y = 1
////}
verify.codeFixAll({
fixAllDescription: "Switch each misused '=' to ':'",
fixId: "fixPropertyAssignment",
newFileContent:
`const a = {
x: 1,
y: 1,
z: 1
}
const b = {
x: 1,
y: 1
}
const c = {
x: 1,
y: 1
}`
});