Home > Net >  How do I use the generic argument as an option in typescript
How do I use the generic argument as an option in typescript

Time:06-15

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.

Playground Link

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

  • Related