I have a function that is a wrapper for axios.request
.
I send a Message type along with config so that I can create a new Message with the response.data
.
I have multiple types of Messages, so I am creating a generic TMessage
type to handle this:
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);
});
}
I can now request with a message type and know what type of response I am getting:
RestClient.request(config, SomeMessage).then((response: SomeMessage) => {
// response is of type SomeMessage, I have intellisense to help
resolve(response);
});
I want to make this messageType optional, as some requests don't have a useful response and don't need to be instantiated into a new message.
Is there a way in TypeScript to do this? The following code uses Union Types and compiles, but it does not enforce the messageType to match the return type, making it a bit redundant.
I want a Promise<TMessage>
return type if messageType is supplied. Otherwise I want a Promise<Axios.AxiosXHR<any>>
return type
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);
});
You can define different signatures for the method:
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}
) {
...
}
This feature is described in the Overloads part of the docs:
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
More info in the link.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With