diff --git a/commands/dispatcher.test.ts b/commands/dispatcher.test.ts index efdd166..83e7a32 100644 --- a/commands/dispatcher.test.ts +++ b/commands/dispatcher.test.ts @@ -7,7 +7,7 @@ import { viewportPanCommand } from "./viewport"; describe("command dispatcher", () => { test("throws for unknown commands", () => { const store = createAppStore(createInitialAppState("Test"), createCommandRegistry([])); - expect(() => store.dispatch("missing", undefined)).toThrow("Unknown command: missing"); + expect(() => store.dispatch("missing" as never, undefined as never)).toThrow("Unknown command: missing"); }); test("dispatch applies command result to store", () => { diff --git a/commands/dispatcher.ts b/commands/dispatcher.ts index 883e3a7..1ce9a61 100644 --- a/commands/dispatcher.ts +++ b/commands/dispatcher.ts @@ -1,8 +1,9 @@ import type { AppState } from "@editor/state"; import type { CommandContext } from "./command"; +import type { CommandId, CommandPayloads } from "./payloads"; import type { CommandRegistry } from "./registry"; -export type Dispatch = (commandId: string, payload: TPayload) => AppState; +export type Dispatch = (commandId: TCommandId, payload: CommandPayloads[TCommandId]) => AppState; export type CommandDispatcher = { dispatch: Dispatch; diff --git a/commands/index.ts b/commands/index.ts index 6df89aa..8c7463c 100644 --- a/commands/index.ts +++ b/commands/index.ts @@ -1,5 +1,6 @@ export type { Command, CommandContext } from "./command"; export type { CommandDispatcher, Dispatch } from "./dispatcher"; +export type { CommandId, CommandPayloads } from "./payloads"; export { createCommandDispatcher } from "./dispatcher"; export type { CommandRegistry } from "./registry"; export { createCommandRegistry } from "./registry"; diff --git a/commands/payloads.ts b/commands/payloads.ts new file mode 100644 index 0000000..b301717 --- /dev/null +++ b/commands/payloads.ts @@ -0,0 +1,16 @@ +import type { + ViewportPanPayload, + ViewportSetSizePayload, + ViewportSetZoomPayload, + ViewportZoomAroundPointPayload, +} from "./viewport"; + +export type CommandPayloads = { + "viewport.pan": ViewportPanPayload; + "viewport.setZoom": ViewportSetZoomPayload; + "viewport.zoomAroundPoint": ViewportZoomAroundPointPayload; + "viewport.setSize": ViewportSetSizePayload; + "viewport.reset": void; +}; + +export type CommandId = keyof CommandPayloads; diff --git a/input/keyboard.ts b/input/keyboard.ts index 16ede28..8f2e2dc 100644 --- a/input/keyboard.ts +++ b/input/keyboard.ts @@ -1,4 +1,5 @@ import type { Dispatch } from "@commands/dispatcher"; +import type { CommandId, CommandPayloads } from "@commands/payloads"; export type Keybind = string; @@ -13,9 +14,9 @@ export type KeybindEvent = { export type GlobalKeybindConsumer = (event: KeybindEvent) => boolean; -export type CommandKeybind = { - commandId: string; - payload?: unknown; +export type CommandKeybind = { + commandId: TCommandId; + payload: CommandPayloads[TCommandId]; }; export type KeybindMap = ReadonlyMap;