The behavior I'm looking for can be implemented with overloading:
function fun(elType: "input", params: Input): number;
function fun(elType: "swtich", params: Switch): number;
function fun(){
return 2
}
Where if I run:
fun("swtich", SOMETHING_OF_SHAPE_SWITCH) //compiles
fun("input", SOMETHING_OF_SHAPE_INPUT) // error
fun("input", SOMETHING_OF_SHAPE_INPUT) //compiles
I was wondering if it can be done by checking the parameter directly:
interface Input {
a: 2
}
interface Switch {
b: 2
}
type ElType = {
input: Input,
switch: Switch,
}
const fun = <T extends keyof ElType>(elType: keyof ElType, params: ElType[typeof elType]) => { }
That's as close as I got but it allows both:
fun("input", {
b: 2
})
fun("input", {
a: 2
})
It seems that I'm close, but I'm a) not quite sure what's happening in this last example and b) not sure how to achieve the desired bahaviour.
It seems what I want to do is:
const fun = <T extends keyof ElType>(elType: keyof ElType, params: ElType[elType]) => {}
But I get the error: type 'elType' cannot be used as an index type.
Here's a tsplayg4round I'm using if you want to play around.
I've seen several libraries implement this pattern so I was wondering what's the most idiomatic way of doing it.
CodePudding user response:
You've defined the generic T
but haven't used it! TypeScript doesn't know what to do with it so it ignores it.
<T extends keyof ElType>(elType: T, params: ElType[T]) => ...
Using it here allows TypeScript to infer what T
is from elType
, and once it knows what T
is, you can use ElType[T]
to get the right params.