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
CodePudding user response:
class Test<Evmt> {
subscribe<CurrentEeventKey extends Evmt>(arg: CurrentEeventKey) {
//here the type is being picked up correctly
console.log(arg)
return arg
}
}
You have set the default generic value when you need extends
CodePudding user response:
To force TypeScript to use the default generic argument type for the Test class, you can use a generic constraint on the CurrentEeventKey type parameter. This will ensure that the type of the CurrentEeventKey type parameter is always the same as the Evmt type parameter passed to the Test class.
Here is an example of how you can do this:
const EventKeys = {
openItem: 'openItem',
changeActiveItem: 'changeActiveItem',
selectionToggled: 'selectionToggled',
} as const
type EventKeys = keyof typeof EventKeys
class Test<Evmt> {
subscribe<CurrentEeventKey extends Evmt = 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"
With this change, the type of the abc variable will be inferred as an error, since the '11223' value is not a member of the EventKeys type.
CodePudding user response:
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
// ^?
}
}