以下是Typecript编译器诅咒的代码:
use(path: PathParams, ...handlers: RequestHandler[]): this
use(path: PathParams, ...handlers: RequestHandlerParams[]): this
use(...handlers: RequestHandler[]): this
use(...handlers: RequestHandlerParams[]): this {
// ...
return this;
}
错误TS2394:过载签名与功能实现不兼容。
我无法理解如何正确地执行过载。你能说出挖掘的方向吗?
答案 0 :(得分:3)
你走了:
注意:发明了PathParams
,RequestHandler
和RequestHandlerParams
的类型,但关键是它们是截然不同且不兼容的
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;
}
}
请注意,在创建重载定义时,消费者无法使用实现签名。只有没有实现的签名可用。这就是为什么我在你的例子中添加了一个额外的签名。
这样做的原因是,为了使第一个参数“可选”,我们需要给它一个可能与的数组元素类型兼容的类型< / em>可能的其余参数类型。
您当然可以将实现签名中的参数类型指定为any
和any[]
,而不会影响您的消费者的类型安全(实现签名不是接口的一部分),但是,通过使用精确,结构良好的联合类型,您可以使用类型保护来区分参数并验证实现是否处理它们。
这意味着您需要在函数实现中通过逻辑确定第一个参数是否实际为PathParams
。