如何修复 no-unsafe-any 规则?

Posted

技术标签:

【中文标题】如何修复 no-unsafe-any 规则?【英文标题】:How to fix no-unsafe-any rule? 【发布时间】:2019-02-22 06:48:46 【问题描述】:

我正在使用 TSLint 来检查我的 Angular TypeScript 代码。我启用了no-unsafe-any 规则,因为对我来说,永远不要假设any 类型的属性是一个很好的规则。

问题是该规则在我的某些代码上报告了错误,除了禁用该规则之外,我无法以任何方式修复这些错误。根据以下规则无效的代码示例。

public intercept(request: HttpRequest<>, next: HttpHandler): Observable<HttpEvent<>> 
  return next
    .handle(request)
    .pipe(
      catchError(error => 
        if (error && error.status === httpCodeUnauthorized) 
          // Auto logout if unathorized
          this.authenticationService.logout();
        

        const errorMessage = (error.error && error.error.message) || error.statusText;

        return throwError(errorMessage);
      ),
    );

Linter 在 2 行报告 4 个错误:

ERROR: /home/robert/programming/npc/gui/src/app/core/authentication/unauthorized.interceptor.ts[24, 24]: Unsafe use of expression of type 'any'.
ERROR: /home/robert/programming/npc/gui/src/app/core/authentication/unauthorized.interceptor.ts[29, 33]: Unsafe use of expression of type 'any'.
ERROR: /home/robert/programming/npc/gui/src/app/core/authentication/unauthorized.interceptor.ts[29, 48]: Unsafe use of expression of type 'any'.
ERROR: /home/robert/programming/npc/gui/src/app/core/authentication/unauthorized.interceptor.ts[29, 72]: Unsafe use of expression of type 'any'

2 个有问题的行是:

if (error &amp;&amp; error.status === httpCodeUnauthorized) const errorMessage = (error.error &amp;&amp; error.error.message) || error.statusText;

问题的根源在于catchError(Rxjs 库函数)的处理程序的error 参数具有any 类型。我知道error 可以是任何类型,因此假设它定义了任何属性是不安全的,但我会在实际引用它们之前首先检查这些属性是否存在,这对我来说似乎是安全的。

我可以/应该做什么来让 linter/TypeScript 编译器相信它是安全的并通过规则?

【问题讨论】:

如果你只是把这行换成if (error) ... ,问题会持续吗? @Cerberus 不幸的是,它仍然报告 4 个错误。 【参考方案1】:

在 Angular 的情况下,错误应该始终属于 HttpErrorResponse 类型

catchError((error: HttpErrorResponse) => 
//...

也就是说,在您的代码中,您查看error.error,它在HttpErrorResponse 中定义为any,因此您可能应该使用类型保护来检查并将其转换为错误对象。不是没有必要定义Error - 它应该由打字稿基类型定义。

function isError(value: any | undefined): value is Error 
  return error && ((error as Error).message !== undefined);

然后在

中使用
const errorMessage = isError(error.error) ? error.error.message : error.statusText;

【讨论】:

它确实摆脱了no-unsafe-any 错误。但随后 linter 报告:ERROR: (strict-type-predicates) /home/robert/programming/npc/gui/src/app/core/authentication/unauthorized.interceptor.ts[15, 20]: Expression is always true. 在线 return error &amp;&amp; ((error as Error).message !== undefined);。我删除了比较运算符,将其更改为return error &amp;&amp; (error as Error).message;,错误消失了。我不明白为什么。你知道为什么吗?【参考方案2】:

你有两个选择,当你知道error 总是有一个特定的类型时,你可以只注解这个类型。如果不能确定,可以使用type guard。

类型注释

使用类型注释,您可以简单地告诉编译器,您期望error 是某种类型。您可以使用这种方法完全避免 any 类型:

interface Error 
    status: string,
    statusText: string,
    error:  message: string | undefined  | undefined;


catchError((error: Error | undefined) => 
    //...

类型保护

只要值可能属于某种类型,但不一定必须属于那种类型,您就可以使用类型保护。类型保护将检查类型,并在以下块中,变量将是检查的类型:

function isError(value: any | undefined): value is Error 
    return error && ((error as Error).status !== undefined);


catchError(error => 
    if (isError(error)) 
        //Inside this block, error will be of type Error
    

【讨论】:

使用类型注解,如果error不是Error类型会发生什么?它会引发运行时错误吗?此外,这两种解决方案对我来说都有些矫枉过正,因为这样的情况很多,而每一种都需要声明不同的类型注释或类型保护。 在 JS 代码中剥离了类型注解。它不会因为类型错误而引发错误,但您的程序可能无法按预期工作。并且类型注释并不过分,它只是 TS(如果您选择 noImplicityAny 作为一个非常常见的选项)。类型保护提供了额外的功能,即基于类型的不同执行路径。

以上是关于如何修复 no-unsafe-any 规则?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 SQL Server 查询中的排序规则冲突?

急,WordPress幻灯片插件RevSlider漏洞如何修复啊?

如何修复drv?

修复 VSCode 中的排序键 ESLint 规则

如何修复mapreduce中mapper的setup方法给出的字符串值的不规则行为?

如何在 VS Code 编辑器中使用 ESLint + Airbnb 规则 + TypeScript + Stylelint 为 SCSS 配置 Vue CLI 4,并在保存时自动修复?