Home > Mobile >  Any way to elide type arguments in TypeScript when irrelevant?
Any way to elide type arguments in TypeScript when irrelevant?

Time:11-25

I have a function like so:

function progress<T>(data: JsonApiQueryData<T>): number {
  const { links, meta } = data.getMeta();
  if (!links.next) {
    return 1;
  }

  const url = new URL(links.next);
  return parseInt(url.searchParams.get('page[offset]')) / meta.total;
}

where JsonApiQueryData is defined as:

export declare class JsonApiQueryData<T> {
    protected jsonApiModels: Array<T>;
    protected metaData: any;
    constructor(jsonApiModels: Array<T>, metaData?: any);
    getModels(): T[];
    getMeta(): any;
}

As you can see from the body of progress, I am not doing anything to or with the underlying T type, so I would love to be able to remove the type argument from it.

Naively attempting this, like so:

function progress(data: JsonApiQueryData): number {
  ...
}

gives me an unfortunate but not surprising error:

Generic type 'JsonApiQueryData<T>' requires 1 type argument(s).

Update

I should have clarified when initially asking, but the JsonApiQueryData is a library type that I am unable to change (easily). From the (prompt and pretty great) responses I've seen so far, the best way to achieve exactly what I want involves changing that type (to something like class JsonApiQueryData<T = any> or class JsonApiQueryData<T = unknown>). Sorry for my inadvertent goalpost moving.

CodePudding user response:

You can define your type as follows:

export declare class JsonApiQueryData<T = unknown>

and then you can define your function progress without any type annotations. Note that it will mean something slightly different, namely

function progress(data: JsonApiQueryData<unknown>): number {

instead of

function progress<T>(data: JsonApiQueryData<T>): number {

but that should work fine in your case.

CodePudding user response:

You could use an interface instead.

// interface declaration
export interface HasMetaData
{
    getMeta(): any;
}

// implment interface
export declare class JsonApiQueryData<T> implements HasMetaData {
    protected jsonApiModels: Array<T>;
    protected metaData: any;
    constructor(jsonApiModels: Array<T>, metaData?: any);
    getModels(): T[];
    getMeta(): any;
}

Usage :

// no need of any generic type
function progress(data: HasMetaData): number {
  // accessing getMeta throught HasMetaData
  const { links, meta } = data.getMeta();
  if (!links.next) {
    return 1;
  }

  const url = new URL(links.next);
  return parseInt(uri.searchParams.get('page[offset]')) / meta.total;
}
  • Related