基于可选函数参数的不同 return 类型 - Typescript

Different return types based on optional function parameter - Typescript

我有一个函数是 axios.request 的包装器。

我将消息类型与配置一起发送,以便我可以使用 response.data 创建新消息。

我有多种消息类型,因此我正在创建一个通用 TMessage 类型来处理此问题:

public request<TMessage extends BaseMessage<TMessage>>(
    config: Axios.AxiosXHRConfig<any>, 
    messageType: {new (message: string): TMessage}
): Promise<TMessage> {
    return new Promise((resolve, reject) => {
        axios.request(config).then((response: Axios.AxiosXHR<any>) => {
            try {
                let message = new messageType(response.data);
                resolve(message);
            } catch (err) {
                reject(err);
            }
        }, reject);
    });
}

我现在可以请求消息类型并知道我得到的响应类型:

RestClient.request(config, SomeMessage).then((response: SomeMessage) => {
  // response is of type SomeMessage, I have intellisense to help
  resolve(response);
});

我想让这个 messageType 成为可选的,因为有些请求没有有用的响应,不需要实例化到新消息中。

TypeScript 有办法做到这一点吗?以下代码使用 Union Types 并编译,但它没有强制 messageType 匹配 return 类型,因此有点多余。

如果提供了 messageType,我想要 Promise<TMessage> return 类型。否则我想要一个 Promise<Axios.AxiosXHR<any>> return 类型

public request<TMessage extends BaseMessage<TMessage>>(
    config: Axios.AxiosXHRConfig<any>, 
    messageType?: {new (message: string): TMessage}
): Promise<TMessage | Axios.AxiosXHR<any>> {
  ...

-

RestClient.request(config, SomeMessage).then((response: OtherMessage) => {
  // this compiles, ideally it should complain about the mismatch of message types
  resolve(response);
});

您可以为方法定义不同的签名:

public request<TMessage extends BaseMessage<TMessage>>(
    config: Axios.AxiosXHRConfig<any>, 
    messageType: {new (message: string): TMessage}
): Promise<TMessage>;
public request(
    config: Axios.AxiosXHRConfig<any>
): Promise<Axios.AxiosXHR<any>>;
public request<TMessage extends BaseMessage<TMessage>>(
    config: Axios.AxiosXHRConfig<any>, 
    messageType?: {new (message: string): TMessage}
) {
    ...
}

编辑

此功能在文档的 Overloads 部分进行了描述:

JavaScript is inherently a very dynamic language. It’s not uncommon for a single JavaScript function to return different types of objects based on the shape of the arguments passed in

link 中的更多信息。