Tengo una función que es un contenedor para axios.request .
Envío un tipo de mensaje junto con la configuración para poder crear un nuevo mensaje con la response.data .
Tengo varios tipos de Mensajes, por lo que estoy creando un tipo de TMessage genérico para manejar esto:
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); }); }Ahora puedo solicitar con un tipo de mensaje y saber qué tipo de respuesta estoy recibiendo:
RestClient.request(config, SomeMessage).then((response: SomeMessage) => { // response is of type SomeMessage, I have intellisense to help resolve(response); });Quiero que este tipo de mensaje sea opcional, ya que algunas solicitudes no tienen una respuesta útil y no es necesario instanciarlas en un nuevo mensaje.
¿Hay alguna manera en TypeScript para hacer esto? El siguiente código usa Union Types y compila, pero no impone el tipo de mensaje para que coincida con el tipo de retorno, lo que lo hace un poco redundante.
Quiero un tipo de retorno Promise<TMessage> si se proporciona messageType. De lo contrario, quiero un tipo de retorno 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); });Puede definir diferentes firmas para el método:
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} ) { ... }Esta característica se describe en la parte de sobrecargas de los documentos:
JavaScript es inherentemente un lenguaje muy dinámico. No es raro que una sola función de JavaScript devuelva diferentes tipos de objetos según la forma de los argumentos pasados en
Más información en el enlace.