是否有 eslint 规则来防止在单行 if 语句中赋值?
Is there an eslint rule to prevent assignment in a single line if statement?
我正在尝试查找是否存在允许以下任何一项的非插件 eslint 规则:
function(x) {
let count = 0;
if (doIncrement(x)) count++
else (doDecrement(x)) count--
if (count >=10) return "over nine";
else return "keep counting";
}
但唯一的错误是:
let listOfThings = [];
if (treatAsString) listOfThings[0] = myString.trim();
else listOfThings = [...myString.split(',').map(stringPart => stringPart.trim())];
// or
let name = '';
if (hasFirstAndLAstName) name = `${firstName} ${lastName}`;
else name = `${emailAddress}`;
赞成像这样使用三元赋值:
const listOfThings = treatAsString
? [myString.trim()]
: [...myString.split(',').map(stringPart => stringPart.trim())];
// or
let name = hasFirstAndLAstName ? `${firstName} ${lastName}` : emailAddress;
不涉及插件的 eslint 是否存在该规则(或规则组合)?
目前没有非插件的。
事实上,即使像 prefer-ternary 这样的插件规则也不会捕捉到复杂的情况,例如你的失败案例,包括索引字段分配与完全重新分配,我将其归类为 'uber-complex'。
仅使用基础 ESLint,您可以尝试 no-restricted-syntax
rule。它不是特定的,但可以禁止您想要的任何语法。
要了解您希望如何配置此规则,请检查:
- 将你的代码放在一个可以生成抽象语法树 (AST) 的工具中,它会告诉你你想禁止什么。我用的是https://astexplorer.net/
- the ESLint guide on selectors 概述了 如何使用和组合 AST 选择器。它们与 CSS 选择器非常相似,但目标是编程代码。
有了这两个,这就是我想出的。这只是一个示例,您可能需要进一步调整规则:
no-restricted-syntax: ["error", "IfStatement > ExpressionStatement > AssignmentExpression"]
这将禁止在单行 if
语句(和 else
中)赋值。请注意,它 不适用于块 。
允许
let x;
if (Math.random() > 0.5) {
x = 4;
} else {
x = 2;
}
不允许:
let x;
if (Math.random() > 0.5) x = 4;
else x = 2;
作为参考,块体包含赋值的 if 语句的选择器将是 IfStatement > BlockStatement > ExpressionStatement > AssignmentExpression
这只会禁止赋值而不是变量声明。像 const x = 42;
这样的构造在 AST 中属于 VariableDeclaration
,因此 AssignmentExpression
是独立的,并且仅在已声明变量时应用。
尝试在线 ESLint 演示:
/* eslint no-restricted-syntax: ["error", "IfStatement > ExpressionStatement > AssignmentExpression"] */
// allowed
function foo(x) {
let count = 0;
if (doIncrement(x)) count++
else if (doDecrement(x)) count--
if (count >=10) return "over nine";
else return "keep counting";
}
// allowed
function foo() {
const listOfThings = treatAsString
? [myString.trim()]
: [...myString.split(',').map(stringPart => stringPart.trim())];
}
// allowed
function foo() {
let name = hasFirstAndLAstName ? `${firstName} ${lastName}` : emailAddress;
}
// allowed - assignment is not in `if`
function foo() {
let x = 1;
x = 2;
}
// allowed - if statement with blocks
function foo() {
let x;
if (Math.random() > 0.5) {
x = 4;
} else {
x = 2;
}
}
// disallowed
function foo() {
let listOfThings = [];
if (treatAsString) listOfThings[0] = myString.trim();
else listOfThings = [...myString.split(',').map(stringPart => stringPart.trim())];
}
// disallowed
function foo() {
let name = '';
if (hasFirstAndLAstName) name = `${firstName} ${lastName}`;
else name = `${emailAddress}`;
}
// disallowed - single line `if` (even though there is no `else`)
function foo() {
let x = 1;
if (Math.random() > 0.5)
x = 2;
}
Direct link to online ESLint demo
正如我所说,这只是为了展示功能。它不鼓励你使用条件语句(错误消息只是“不要使用这个”)并且可能也没有涵盖你想要的一切(例如,在 if
中的赋值在另一个 if
).但这是一个开始。
不过,您可能想要制作一个自定义插件,它可以更准确地检查您想要的内容并报告更好的错误。对于大多数用例,no-restricted-syntax
规则可能 太 通用。
我正在尝试查找是否存在允许以下任何一项的非插件 eslint 规则:
function(x) {
let count = 0;
if (doIncrement(x)) count++
else (doDecrement(x)) count--
if (count >=10) return "over nine";
else return "keep counting";
}
但唯一的错误是:
let listOfThings = [];
if (treatAsString) listOfThings[0] = myString.trim();
else listOfThings = [...myString.split(',').map(stringPart => stringPart.trim())];
// or
let name = '';
if (hasFirstAndLAstName) name = `${firstName} ${lastName}`;
else name = `${emailAddress}`;
赞成像这样使用三元赋值:
const listOfThings = treatAsString
? [myString.trim()]
: [...myString.split(',').map(stringPart => stringPart.trim())];
// or
let name = hasFirstAndLAstName ? `${firstName} ${lastName}` : emailAddress;
不涉及插件的 eslint 是否存在该规则(或规则组合)?
目前没有非插件的。
事实上,即使像 prefer-ternary 这样的插件规则也不会捕捉到复杂的情况,例如你的失败案例,包括索引字段分配与完全重新分配,我将其归类为 'uber-complex'。
仅使用基础 ESLint,您可以尝试 no-restricted-syntax
rule。它不是特定的,但可以禁止您想要的任何语法。
要了解您希望如何配置此规则,请检查:
- 将你的代码放在一个可以生成抽象语法树 (AST) 的工具中,它会告诉你你想禁止什么。我用的是https://astexplorer.net/
- the ESLint guide on selectors 概述了 如何使用和组合 AST 选择器。它们与 CSS 选择器非常相似,但目标是编程代码。
有了这两个,这就是我想出的。这只是一个示例,您可能需要进一步调整规则:
no-restricted-syntax: ["error", "IfStatement > ExpressionStatement > AssignmentExpression"]
这将禁止在单行 if
语句(和 else
中)赋值。请注意,它 不适用于块 。
允许
let x;
if (Math.random() > 0.5) {
x = 4;
} else {
x = 2;
}
不允许:
let x;
if (Math.random() > 0.5) x = 4;
else x = 2;
作为参考,块体包含赋值的 if 语句的选择器将是 IfStatement > BlockStatement > ExpressionStatement > AssignmentExpression
这只会禁止赋值而不是变量声明。像 const x = 42;
这样的构造在 AST 中属于 VariableDeclaration
,因此 AssignmentExpression
是独立的,并且仅在已声明变量时应用。
尝试在线 ESLint 演示:
/* eslint no-restricted-syntax: ["error", "IfStatement > ExpressionStatement > AssignmentExpression"] */
// allowed
function foo(x) {
let count = 0;
if (doIncrement(x)) count++
else if (doDecrement(x)) count--
if (count >=10) return "over nine";
else return "keep counting";
}
// allowed
function foo() {
const listOfThings = treatAsString
? [myString.trim()]
: [...myString.split(',').map(stringPart => stringPart.trim())];
}
// allowed
function foo() {
let name = hasFirstAndLAstName ? `${firstName} ${lastName}` : emailAddress;
}
// allowed - assignment is not in `if`
function foo() {
let x = 1;
x = 2;
}
// allowed - if statement with blocks
function foo() {
let x;
if (Math.random() > 0.5) {
x = 4;
} else {
x = 2;
}
}
// disallowed
function foo() {
let listOfThings = [];
if (treatAsString) listOfThings[0] = myString.trim();
else listOfThings = [...myString.split(',').map(stringPart => stringPart.trim())];
}
// disallowed
function foo() {
let name = '';
if (hasFirstAndLAstName) name = `${firstName} ${lastName}`;
else name = `${emailAddress}`;
}
// disallowed - single line `if` (even though there is no `else`)
function foo() {
let x = 1;
if (Math.random() > 0.5)
x = 2;
}
Direct link to online ESLint demo
正如我所说,这只是为了展示功能。它不鼓励你使用条件语句(错误消息只是“不要使用这个”)并且可能也没有涵盖你想要的一切(例如,在 if
中的赋值在另一个 if
).但这是一个开始。
不过,您可能想要制作一个自定义插件,它可以更准确地检查您想要的内容并报告更好的错误。对于大多数用例,no-restricted-syntax
规则可能 太 通用。