-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask-guards.ts
More file actions
27 lines (25 loc) · 1.02 KB
/
Copy pathtask-guards.ts
File metadata and controls
27 lines (25 loc) · 1.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
import type { Task, TaskPriority } from '@/types/task';
const STATUSES = new Set(['todo', 'in_progress', 'done', 'archived']);
const PRIORITIES = new Set<number>([1, 2, 3]);
/**
* Runtime validation for data crossing the WebSocket boundary. The socket
* payload is untrusted at runtime (the `Task` type is only a compile-time
* contract), so we verify shape before letting it into React state — a
* malformed event can't silently corrupt the board (e.g. `NaN` sort keys).
*/
export function isTask(value: unknown): value is Task {
if (typeof value !== 'object' || value === null) return false;
const t = value as Record<string, unknown>;
return (
typeof t.id === 'string' &&
typeof t.title === 'string' &&
typeof t.status === 'string' &&
STATUSES.has(t.status) &&
typeof t.priority === 'number' &&
PRIORITIES.has(t.priority as TaskPriority) &&
Array.isArray(t.tags) &&
t.tags.every((tag) => typeof tag === 'string') &&
typeof t.createdAt === 'string' &&
typeof t.updatedAt === 'string'
);
}