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

Posted

技术标签:

【中文标题】基于可选函数参数的不同返回类型 - Typescript【英文标题】:Different return types based on optional function parameter - Typescript 【发布时间】:2017-06-01 16:34:27 【问题描述】:

我有一个函数是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匹配返回类型,有点多余。

如果提供了 messageType,我想要一个 Promise&lt;TMessage&gt; 返回类型。否则我想要一个Promise&lt;Axios.AxiosXHR&lt;any&gt;&gt; 返回类型

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);
);

【问题讨论】:

【参考方案1】:

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

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 函数返回不同类型的对象 基于传入参数的形状

链接中的更多信息。

【讨论】:

第二个需要type参数吗? 这些必须是抽象方法吗?还是他们需要方法体? @AndrewEisenberg 通过文档链接检查我修改后的答案 @NitzanTomer 不错。我不知道函数重载。

以上是关于基于可选函数参数的不同返回类型 - Typescript的主要内容,如果未能解决你的问题,请参考以下文章

函数重载与可选参数

Python函数:函数的定义语法调用参数类型(必选参数缺省参数可选参数关键字可选参数)return返回值函数嵌套

可选参数后的重载

TS学习之函数

函数的打字稿联合/交集类型

如何根据枚举参数返回不同的类型