-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample-types.ts
More file actions
109 lines (100 loc) · 3.02 KB
/
example-types.ts
File metadata and controls
109 lines (100 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { createMachine, Coremachine, Infer } from "./index";
// Demo: Creating a typed state machine
const todoMachine = createMachine({
initial: "idle" as const,
context: {
todos: [] as Array<{ id: string; text: string; completed: boolean }>,
filter: "all" as "all" | "active" | "completed",
user: {
id: "",
name: "",
preferences: {
theme: "light" as "light" | "dark",
autoSave: true,
},
},
},
states: {
idle: {
on: {
ADD_TODO: {
target: "idle",
action: (ctx, todo: { text: string }) => {
// ctx is fully typed! IntelliSense will work perfectly here
ctx.todos.push({
id: Math.random().toString(),
text: todo.text,
completed: false,
});
},
},
TOGGLE_TODO: {
target: "idle",
action: (ctx, todoId: string) => {
const todo = ctx.todos.find((t) => t.id === todoId);
if (todo) {
todo.completed = !todo.completed;
}
},
},
SET_FILTER: {
target: "idle",
action: (ctx, filter: "all" | "active" | "completed") => {
ctx.filter = filter;
},
},
LOGIN_USER: {
target: "idle",
action: (ctx, user: { id: string; name: string }) => {
ctx.user.id = user.id;
ctx.user.name = user.name;
},
},
UPDATE_THEME: {
target: "idle",
action: (ctx, theme: "light" | "dark") => {
ctx.user.preferences.theme = theme;
},
},
},
},
},
});
// Extract action signatures for external use
type TodoActions = Infer<typeof todoMachine>;
// This will be:
// {
// ADD_TODO: { text: string };
// TOGGLE_TODO: string;
// SET_FILTER: 'all' | 'active' | 'completed';
// LOGIN_USER: { id: string; name: string };
// UPDATE_THEME: 'light' | 'dark';
// }
// Function that safely works with the machine
function createTodoHelper(coremachine: Coremachine<typeof todoMachine>) {
const currentState = coremachine.state;
return {
addTodo: (text: string) => coremachine.action("ADD_TODO", { text }),
toggleTodo: (id: string) => coremachine.action("TOGGLE_TODO", id),
setFilter: (filter: "all" | "active" | "completed") =>
coremachine.action("SET_FILTER", filter),
getFilteredTodos: () => {
const { todos, filter } = coremachine.context;
switch (filter) {
case "active":
return todos.filter((t) => !t.completed);
case "completed":
return todos.filter((t) => t.completed);
default:
return todos;
}
},
// Type-safe access to context
getStats: () => ({
total: coremachine.context.todos.length,
completed: coremachine.context.todos.filter((t) => t.completed).length,
active: coremachine.context.todos.filter((t) => !t.completed).length,
}),
};
}
export { todoMachine, createTodoHelper, type TodoActions };