Home > Mobile >  Typescript: method signature based on generic
Typescript: method signature based on generic

Time:02-22

I've the following generic class:

export class AClass<Data = void> {

refresh(data: Data): void {}

}

I would like the signature of the refresh method to be:

refresh(){} // when Data = void
refresh(data: Data){} // otherwise

I do not want to make the data argument optional

refresh(data?: Data){} // not what I want because if data is different than "void" the arguments will be optional as well

The best I've been able to do is to use a variable holding a function instead of using a method.

export class AClass<Data = void> {
    refresh: Data extends void ? () => void : (data: Data) => void = (...arg){
        console.log(...arg);
    }
}

I doubt we can have conditional method (class) signature defined within the same class, but is this accurate ?

[EDIT] Why this question ?

Here is a TS class:

class Example {
  aMethod () {
    console.log(`I am a method`)
  };

  aVariable = () => {console.log(`I am a variable holding a function`)}
}

This will be transpiled into this:

"use strict";
class Example {
    constructor() {
        this.aVariable = () => { console.log(`I am a variable holding a function`); };
    }
    aMethod() {
        console.log(`I am a method`);
    }
    ;
}

We can clearly while both will eventually achieve the same however the method one is closer to the "native" es6 method implementation. For this reason, I would like to find out if there is a way to type a class's method so that I will still be using a method instead of a variable.

CodePudding user response:

I do not see any issues with your code:

class AClass<T = void> {
    refresh(data: T): void {
        console.log(data);
    }
}

const instance = new AClass();

instance.refresh(); // log: undefined
instance.refresh('test'); // Compiler error

const instance2 = new AClass<string>();

instance2.refresh(); // Compiler error
// log: compiler error if not present
instance2.refresh('compiler error if not present');

transpiled to:

"use strict";
class AClass {
    refresh(data) {
        console.log(data);
    }
}
const instance = new AClass();
instance.refresh();
const instance2 = new AClass();
instance2.refresh('test');
  • Related