CodeQL 文档

无法访问的方法重载

ID: js/unreachable-method-overloads
Kind: problem
Security severity: 
Severity: warning
Precision: high
Tags:
   - correctness
   - typescript
Query suites:
   - javascript-security-and-quality.qls

单击查看 CodeQL 存储库中的查询

TypeScript 编译器必须选择在调用具有多个重载的方法时调用哪个特定重载。编译器将始终选择第一个不会导致任何类型错误的文本重载。这依赖于在函数调用中提供的参数。

对于不熟悉 TypeScript 类型系统的程序员来说,这种行为可能不直观,并且在某些情况下会导致程序员编写一个只有第一个重载才能使用的重载方法。

建议

如果具有更多类型参数的重载位于具有较少参数的类似重载之前,请重新排序方法重载。或者,通过创建一个返回多个重载的返回值的联合的单个重载,将具有相同参数类型的多个重载合并。

示例

在下面的示例中,程序员试图通过创建具有相同参数类型的多个重载来表达一个方法可以返回多个可能的值。但是,TypeScript 编译器将始终选择第一个重载。

interface Foo {
    getParsedThing(id: string): string[];
    getParsedThing(id: string): number[];
    getParsedThing(id: string): object[];
}

可以通过将重载合并为单个方法签名来修复此错误,该签名返回先前返回值的联合。

interface Foo {
    getParsedThing(id: string): object[] | number[] | string[];
}

在下面的示例中,一个接口Foo声明了一个方法create(),该方法有两个重载。两个重载之间唯一的区别是第一个重载中的类型参数T。TypeScript 编译器将始终在调用create()时使用第一个重载,因为如果未提供类型参数T,将使用默认类型。此默认类型在 TypeScript 3.5+ 中为unknown,在早期版本中为{}

interface Foo {
    create<T>(a: string): MyObject<T>;
    create(a: string): MyObject<any>;
}

在此示例中,通过切换两个重载的顺序来修复错误。在此修复版本中,如果使用显式类型参数调用create()方法,则将使用第二个重载,因为第一个重载会导致类型错误。

interface Foo {
    create(a: string): Array<any>;
    create<T>(a: string): Array<T>;
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私