使用 switch 时 tslint 抱怨 "statements must be filtered with an if statement"
tslint complaining "statements must be filtered with an if statement" when using switch
假设我有以下方法:
getErrorMessage(state: any, thingName?: string) {
const thing: string = state.path || thingName;
const messages: string[] = [];
if (state.errors) {
for (const errorName in state.errors) {
switch (errorName) {
case 'required':
messages.push(`You must enter a ${thing}`);
break;
case 'minlength':
messages.push(`A ${thing} must be at least ${state.errors['minlength'].requiredLength}characters`);
break;
case 'pattern':
messages.push(`The ${thing} contains illegal characters`);
break;
case 'validateCardNumberWithAlgo':
messages.push(`Card doesnt pass algo`);
break;
}
}
}
return messages;
}
当我运行
ng lint
我收到以下错误:
for (... in ...) 语句必须用 if 语句过滤
查看类似 我认为该答案不适用于我的情况。毕竟 switch 语句属于 if-else-if 阶梯的范畴。
tslint 应该将 switch 语句视为 if 语句的形式,但它没有?!
这让我很好奇,所以我检查了 TSlint source code 这条规则。它有一个名为 isFiltered
的函数,它似乎只检查 ts.SyntaxKind.IfStatement
,而不检查 ts.SyntaxKind.SwitchStatement
.
function isFiltered({statements}: ts.Block): boolean {
switch (statements.length) {
case 0: return true;
case 1: return statements[0].kind === ts.SyntaxKind.IfStatement;
default:
return statements[0].kind === ts.SyntaxKind.IfStatement && nodeIsContinue((statements[0] as ts.IfStatement).thenStatement);
}
}
因此,除非您想将对象转换为数组,否则您将需要使用您提供的 link 中的修复程序。 Object.keys
或 if
语句:
for (const errorName in state.errors) {
if (state.errors.hasOwnProperty(errorName)) {
switch (errorName) {
有趣的是,您可以使用任何类型的 if
语句,错误都会消失。没有检查您是否在调用 hasOwnProperty
.
该规则旨在防止您在使用 for .. in 时访问对象原型上定义的属性。
然而,您可以重构代码以不使用它,并使其更易于维护和开发。
例如:
interface ErrorMessageFactory {
(thing: string, state?): string
}
type Errors = 'required' | 'minlength' | 'pattern' | 'validateCardNumberWithAlgo'
let errorFactory: {[e in Errors]: ErrorMessageFactory} = {
required: (thing) => `You must enter a ${thing}`,
minlength: (thing, state) => `A ${thing} must be at least ${state.errors['minlength'].requiredLength}characters`,
pattern: (thing) => `The ${thing} contains illegal characters`,
validateCardNumberWithAlgo: (thing) => `Card doesnt pass algo`
}
function getErrorMessage(state: any, thingName?: string) {
if (state.errors) {
return state.errors.map((error) => errorFactory[error](thingName, state));
}
return [];
}
您可以在 playground 中看到一个有效的片段 here。
假设我有以下方法:
getErrorMessage(state: any, thingName?: string) {
const thing: string = state.path || thingName;
const messages: string[] = [];
if (state.errors) {
for (const errorName in state.errors) {
switch (errorName) {
case 'required':
messages.push(`You must enter a ${thing}`);
break;
case 'minlength':
messages.push(`A ${thing} must be at least ${state.errors['minlength'].requiredLength}characters`);
break;
case 'pattern':
messages.push(`The ${thing} contains illegal characters`);
break;
case 'validateCardNumberWithAlgo':
messages.push(`Card doesnt pass algo`);
break;
}
}
}
return messages;
}
当我运行
ng lint
我收到以下错误:
for (... in ...) 语句必须用 if 语句过滤
查看类似
tslint 应该将 switch 语句视为 if 语句的形式,但它没有?!
这让我很好奇,所以我检查了 TSlint source code 这条规则。它有一个名为 isFiltered
的函数,它似乎只检查 ts.SyntaxKind.IfStatement
,而不检查 ts.SyntaxKind.SwitchStatement
.
function isFiltered({statements}: ts.Block): boolean {
switch (statements.length) {
case 0: return true;
case 1: return statements[0].kind === ts.SyntaxKind.IfStatement;
default:
return statements[0].kind === ts.SyntaxKind.IfStatement && nodeIsContinue((statements[0] as ts.IfStatement).thenStatement);
}
}
因此,除非您想将对象转换为数组,否则您将需要使用您提供的 link 中的修复程序。 Object.keys
或 if
语句:
for (const errorName in state.errors) {
if (state.errors.hasOwnProperty(errorName)) {
switch (errorName) {
有趣的是,您可以使用任何类型的 if
语句,错误都会消失。没有检查您是否在调用 hasOwnProperty
.
该规则旨在防止您在使用 for .. in 时访问对象原型上定义的属性。
然而,您可以重构代码以不使用它,并使其更易于维护和开发。
例如:
interface ErrorMessageFactory {
(thing: string, state?): string
}
type Errors = 'required' | 'minlength' | 'pattern' | 'validateCardNumberWithAlgo'
let errorFactory: {[e in Errors]: ErrorMessageFactory} = {
required: (thing) => `You must enter a ${thing}`,
minlength: (thing, state) => `A ${thing} must be at least ${state.errors['minlength'].requiredLength}characters`,
pattern: (thing) => `The ${thing} contains illegal characters`,
validateCardNumberWithAlgo: (thing) => `Card doesnt pass algo`
}
function getErrorMessage(state: any, thingName?: string) {
if (state.errors) {
return state.errors.map((error) => errorFactory[error](thingName, state));
}
return [];
}
您可以在 playground 中看到一个有效的片段 here。