Working purely on a type level. Given the following scenario:
type Command<Type extends string> = { type: Type };
type Handler<Type extends string, Dependencies> = (cmd: Command<Type>, deps: Dependencies) => void;
type CommandA = Command<"A">;
type CommandB = Command<"B">;
type MockServiceA = { foo: () => boolean };
type MockServiceB = { bar: () => boolean };
type HandlerA = Handler<"A", { someService: MockServiceA }>;
type HandlerB = Handler<"B", { someService: MockServiceA; anotherService: MockServiceB }>;
type HandlerSum = HandlerA | HandlerB; // there might be n handlers in the sum type
I would like to create a mapped type that gives me a dictionary of command types and their dependencies.
type OnlyHalfwayThere = {
[K in Parameters<HandlerSum>[0]["type"]]: Parameters<HandlerSum>[1]; // <--- this gives me a union of all dependencies
};
// basically what I want is a where clause...
// get the second function argument of the handler where the first function argument matches the key selector [K in Parameters<HandlerSum>[0]["type"]]
// desired outcome
type Outcome = {
A: { someService: MockServiceA };
B: { someService: MockServiceA; anotherService: MockServiceB };
};
CodePudding user response:
You can rewrite the mapped type like this:
type OnlyHalfwayThere = {
[K in Parameters<HandlerSum> as K[0]["type"]]: K[1];
};
Instead of assigning the "type"
value to K
, we assign Parameters<HandlerSum>
to it. We can now use K
to get both K[0]["type"]
and K[1]
.