I have this code:
private descargar<T>(url: string, type: "arraybuffer" | "document" | "blob" | "json" | "text"): Promise<T | null>{
return new Promise(function (resolve) {
// Get file name from url.
var xhr = new XMLHttpRequest();
xhr.responseType = "blob"
xhr.onload = function () {
resolve(xhr.response);
return;
};
xhr.onerror = ()=>resolve(null);
xhr.open("GET", url);
xhr.send();
})
}
And it gets called like this:
const response = await this.descargar<Blob>(url, "blob")
It's redundant because you need to specify Blob twice. What's the alternative?
CodePudding user response:
Say you define a type that maps the string that might be supplied to the type
parameter to its associated type:
type DescargarMap = {
arraybuffer: ArrayBuffer;
document: Document;
blob: Blob;
json: Object;
text: string;
}
(I've taken a best-guess at how these strings map to types... may need fixing)
now, using this map type, you can define your function as follows:
descargar<T extends keyof DescargarMap>(
url: string,
type: T): Promise<DescargarMap[T] | null>{...}
and call it
// `buf` is `ArrayBuffer | null`
const buf = await descargar("", "arraybuffer");
Now, appropriate options for the type
parameter are shown in code-completion hints of the IDE and the return-type is correctly mapped without having to supply the generic parameter.
CodePudding user response:
class SomeClass {
private descargar(
url: string,
type: "arraybuffer"
): Promise<ArrayBuffer | null>;
private descargar(url: string, type: "document"): Promise<Document | null>;
private descargar(url: string, type: "blob"): Promise<Blob | null>;
private descargar(url: string, type: "text"): Promise<string | null>;
private descargar<T>(url: string, type: "json"): Promise<T | null>;
private descargar(
url: string,
type: "arraybuffer" | "document" | "blob" | "json" | "text"
): Promise<any | null> {
return new Promise(function (resolve) {
// Get file name from url.
var xhr = new XMLHttpRequest();
xhr.responseType = type;
xhr.onload = function () {
resolve(xhr.response);
return;
};
xhr.onerror = () => resolve(null);
xhr.open("GET", url);
xhr.send();
});
}
public async test() {
const buf = await this.descargar("/buf", "arraybuffer");
console.log(buf?.byteLength);
const object = await this.descargar<{ id: string; name: string }>(
"/text",
"json"
);
console.log(object?.id);
}
}