我有一个函数是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);
});

我想将此消息类型设置为可选,因为有些请求没有有用的响应,也不需要实例化为新消息。
有办法用打字机写吗?下面的代码使用联合类型和编译,但它不强制MaseGeType匹配返回类型,使其有点冗余。
如果提供了messagetype,我想要一个Promise<TMessage>返回类型。否则我想要一个Promise<Axios.AxiosXHR<any>>返回类型
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本质上是一种非常动态的语言。这并不罕见
一个javascript函数返回不同类型的对象
基于传入的参数的形状
链接中有更多信息。

07-24 18:13
查看更多