Search code examples
javascripttypescripttypescript-typingstypescript-genericsreact-typescript

How do we force Typescript to use the default generic argument type here?


const EventKeys = {
  openItem: 'openItem',
  changeActiveItem: 'changeActiveItem',
  selectionToggled: 'selectionToggled',
} as const

type EventKeys = keyof typeof EventKeys


class Test<Evmt>{

    subscribe<CurrentEeventKey = Evmt>(arg:CurrentEeventKey){
      //here the type is being picked up correctly
      console.log(arg)
      return arg
            //     ^?

  }
}


const t1 = new Test<EventKeys>
//     ^?const t1: Test<"openItem" | "changeActiveItem" | "selectionToggled">

const abc = t1.subscribe('11223')
// here the type param should give error since it should take up constructor value here
//     ^? const abc: "11223"

t1.subscribe<'11223'>('11223')
// but here the type param should not give error since it should take the supplied value here


I tried passing the argument and setting a default value. I wanted the function to have the generic type value picked up from the default value passed by the constructor call.So that it doesn't need to be defined again. But when provided on function call it should take that type Inside the function inference works and type is correct


Solution

  • Use two overloads,
    A default one, with inherited argument One without generic inference, defaulting to void Playground

    import { F } from 'ts-toolbelt'
    class Test<Evmt>{
        subscribe<CurrentEeventKey extends Evmt>(arg: CurrentEeventKey): CurrentEeventKey;
        subscribe<CurrentEeventKey = void>(arg: F.NoInfer<CurrentEeventKey>): CurrentEeventKey;
        subscribe<CurrentEeventKey = Evmt>(arg: CurrentEeventKey) {
            //here the type is being picked up correctly
            console.log(arg)
            return arg
            //     ^?
        }
    }