Is there any way to pass an argument to a generic type and infer another ? I’ve tried the following but it shows all possible way.
I cannot pass the state as it, otherwise this would allow the user to play with a reactive object by mutating it, where I want it to only subscribe to it.
type A = {
value: string;
number: number;
}
subscribe<AnotherState extends {}>(
roomId: string,
key: keyof AnotherState,
callback: (
state: AnotherState[typeof key]
) => void
): UnsubscribeFunction;
// can call
subscribe<A>("test", "value", (isAString) => console.log(isAString));
subscribe<A>("test", "number", (isANumber) => console.log(isANumber));
// final implementation
subscribe: (roomId, key, callback) => {
const targetState = roomStateMap.get(roomId);
if (!targetState) throw new Error(`Room ${roomId} not found`);
return subscribeKey(targetState, key, callback);
},
Thanks
>Solution :
Since subscribe is generic, TS can’t infer the exact callback’s argument’s type, I would suggest to use a function factory to create a non-generic (the parameter is inferred) subscribe() function:
type A = {
value: string;
number: number;
}
declare function subscriber<AnotherState extends {}>(
roomId: string
) : <K extends keyof AnotherState>(
key: K,
callback: (state: AnotherState[K]) => void
) => Function;
const subscribe = subscriber<A>("test")
subscribe("value", (isAString) => console.log(isAString)); // string
subscribe("number", (isANumber) => console.log(isANumber)); // number