打字稿错误TS2394:重载签名与函数实现不兼容

Khu*_*rob 5 typescript

这是Typecript编译器诅咒的代码:

use(path: PathParams, ...handlers: RequestHandler[]): this
use(path: PathParams, ...handlers: RequestHandlerParams[]): this
use(...handlers: RequestHandler[]): this
use(...handlers: RequestHandlerParams[]): this {
    // ...
    return this;
}
Run Code Online (Sandbox Code Playgroud)

错误TS2394:重载签名与功能实现不兼容。

我不明白如何正确执行过载。你能告诉挖掘的方向吗?

Alu*_*dad 5

干得好:

注:该类型的PathParamsRequestHandlerRequestHandlerParams被发明,但问题是,他们是不同的和不兼容

export interface PathParams {
  path: string;
  params: {
    id: number,
    [key: string]: string | number
  }
}

export type RequestHandler = (request: RequestHandlerParams) => void;

export interface RequestHandlerParams {
  kind: 'query' | 'route'
  value: string;
}

export default class {
  use(path: PathParams, ...handlers: RequestHandler[]): this
  use(path: PathParams, ...handlers: RequestHandlerParams[]): this
  use(...handlers: RequestHandler[]): this
  use(...handlers: RequestHandlerParams[]): this;
  use(
    pathOrHandlerOrHandlerParam: PathParams | RequestHandler | RequestHandlerParams,
    ...handlers: Array<RequestHandler | RequestHandlerParams>
  ): this {
    // ...
    return this;
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在创建重载定义时,消费者无法使用实现签名。只有没有实现的签名才可用。这就是为什么我在你的例子中添加了一个额外的签名。

这样做的原因是,为了使第一个参数“可选”,我们需要给它一个类型,该类型可能一可能的其余参数类型的数组元素类型兼容。

您当然可以在实现签名中指定参数类型,any并且any[]不会影响消费者的类型安全(实现签名不是接口的一部分)但是,通过使用精确、结构良好的联合类型,您可以使用类型保护区分参数并验证实现处理它们。

这意味着您需要确定第一个参数是否实际上是PathParams函数实现中的过孔逻辑。

  • 这个答案对我有帮助的是关于对使用代码隐藏实现签名的声明。我一直以为所有签名都是可用的。不再! (2认同)