无法实现 Typescript 函数重载

问题描述 投票:0回答:1

接最后一个问题: Typescript:省略类型中的未定义/空属性

使用 TS,我试图通过

request
(下面的代码)为名为
payload
的函数实现重载,它可以接受或不接受
TEndpointsPayload
(当属性包含 null 时,无需传递有效负载) ,

提供以下类型:

export type TEndpointsPayload = {
    getList: null, //No payload required
    open: {
        name: string
    }
    close: {
        name: string
    }
}

export type TEndpointsWithPayload = {
    [K in keyof TEndpointsPayload as TEndpointsPayload[K] extends null ? never : K]: TEndpointsPayload[K]; //Contains the 'open' | 'close'
}; //Will create a type: {'open': {name: string}, 'close': {name: string}}

export type TEndpointsWithoutPayload = {
    [K in keyof TEndpointsPayload as TEndpointsPayload[K] extends null ? K : never]: TEndpointsPayload[K]; //Contains only the 'getList'
}; //Will create a type: {'getList': null}

这是函数重载实现

//This overload signature is not compatible with its implementation signature.ts(2394)
  private async request<T extends keyof TEndpointsWithoutPayload>(endpointName: T): Promise<TEndpointsResponse[T]>;

//Code never fall into this implementation
  private async request<T extends keyof TEndpointsWithPayload>(endpointName: T, payload: TEndpointsWithPayload[T]): Promise<TEndpointsResponse[T]> { ... }

目前我有两个问题,一个是第一个

request
函数有错误

This overload signature is not compatible with its implementation signature.ts(2394)

?
添加到
payload
参数时解决了(但不是我打算做的,因为有效载荷不应该是可选的,但必需/不存在取决于
TEndpointsPayload

其次,这些方法的任何使用都属于第一个

request
实现(又名:只允许在没有有效载荷的情况下传递
request('getList')
)。

我没有做到以下行为:

request('getList')//OK
request('open', {name}) //OK
request('getList', {test}) //ERROR, no payload allow
request('open') // ERROR, payload required

谢谢!任何提示或帮助将不胜感激!

typescript overloading typescript-typings typescript-generics typescript2.0
1个回答
0
投票

在发布这个问题后不久,我就找到了解决方案。 显然,需要声明功能场景和实现处理所有这些场景的第三个场景。 所以正确的函数重载应该是这样的:

    private async request<T extends keyof TEndpointsWithoutPayload>(endpointName: T): Promise<TEndpointsResponse[T]>;
    private async request<T extends keyof TEndpointsWithPayload>(endpointName: T, payload: TEndpointsWithPayload[T]): Promise<TEndpointsResponse[T]>;
    private async request<T extends keyof TEndpointsPayload>(endpointName: T, payload?: TEndpointsPayload[T]): Promise<TEndpointsResponse[T]> {
//handle both scenarios
}

希望对遇到同样问题的人有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.