From ba47dd01d60e5f1ff4b44aa9debb3fc597430a4b Mon Sep 17 00:00:00 2001 From: "Russ T. Fugal" Date: Wed, 19 Aug 2026 11:02:54 -0600 Subject: [PATCH] feat(model): replace enums with erasable const objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TimeUnit, RelationType, ResourceType, ConstraintType and Priority were TypeScript enums — one of the handful of non-erasable constructs, which emit runtime code instead of vanishing when types are stripped. Every type-stripping toolchain (node's built-in stripping, bun, esbuild, oxc/Vite, the Convex bundler) has to special-case them, and node refuses them outright. A downstream workspace consumes this library as source with `erasableSyntaxOnly` set, where these five made it fail to typecheck. Each becomes a const object plus a derived type of the same name, so the value namespace (`TimeUnit.Days`) and the type name both survive. The types become structural unions rather than nominal enums (a loosening), the identifiers can no longer be namespaces or be declaration-merged, and Priority loses its numeric reverse mapping. Nothing in the repo used any of those; checked with greps for `typeof X`, `X[`, `Object.values(X)` and namespace-position uses. `z.enum()` in src/schema/types.ts already accepts a const object under zod 4, so the four schemas are unchanged. Public API: all five are re-exported from src/index.ts, so this is documented in a new CHANGELOG.md. bun test: 584 pass / 12 skip / 1 fail (the pre-existing XlsxWriter named-range failure); bun run typecheck clean; generated/block-meta.json unchanged after regeneration. --- src/model/types.ts | 77 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/model/types.ts b/src/model/types.ts index 33b1a98..e04f565 100644 --- a/src/model/types.ts +++ b/src/model/types.ts @@ -1,43 +1,48 @@ -export enum TimeUnit { - Minutes = "minutes", - Hours = "hours", - Days = "days", - Weeks = "weeks", - Months = "months", - Percent = "percent", -} +export const TimeUnit = { + Minutes: "minutes", + Hours: "hours", + Days: "days", + Weeks: "weeks", + Months: "months", + Percent: "percent", +} as const; +export type TimeUnit = (typeof TimeUnit)[keyof typeof TimeUnit]; -export enum RelationType { - FinishToStart = "FS", - StartToStart = "SS", - FinishToFinish = "FF", - StartToFinish = "SF", -} +export const RelationType = { + FinishToStart: "FS", + StartToStart: "SS", + FinishToFinish: "FF", + StartToFinish: "SF", +} as const; +export type RelationType = (typeof RelationType)[keyof typeof RelationType]; -export enum ResourceType { - Material = "Material", - Work = "Work", - Cost = "Cost", -} +export const ResourceType = { + Material: "Material", + Work: "Work", + Cost: "Cost", +} as const; +export type ResourceType = (typeof ResourceType)[keyof typeof ResourceType]; -export enum ConstraintType { - AsSoonAsPossible = "ASAP", - AsLateAsPossible = "ALAP", - MustStartOn = "MSO", - MustFinishOn = "MFO", - StartNoEarlierThan = "SNET", - StartNoLaterThan = "SNLT", - FinishNoEarlierThan = "FNET", - FinishNoLaterThan = "FNLT", -} +export const ConstraintType = { + AsSoonAsPossible: "ASAP", + AsLateAsPossible: "ALAP", + MustStartOn: "MSO", + MustFinishOn: "MFO", + StartNoEarlierThan: "SNET", + StartNoLaterThan: "SNLT", + FinishNoEarlierThan: "FNET", + FinishNoLaterThan: "FNLT", +} as const; +export type ConstraintType = (typeof ConstraintType)[keyof typeof ConstraintType]; -export enum Priority { - Lowest = 100, - Low = 250, - Medium = 500, - High = 750, - Highest = 1000, -} +export const Priority = { + Lowest: 100, + Low: 250, + Medium: 500, + High: 750, + Highest: 1000, +} as const; +export type Priority = (typeof Priority)[keyof typeof Priority]; export type { ProjectProperties } from "../schema/project.ts"; export type { WorkingTimeRange, CalendarWeekDay, CalendarException } from "../schema/calendar.ts"; -- 2.54.0