typescript / expert
Snippet
Compile-Time State Machine Guards with Phantom Types
Phantom type parameters attach type-level tags to runtime instances without modifying their underlying data structure. This prevents invalid lifecycle state transitions at compile time in core application logic.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type Draft = { state: 'DRAFT' };type Published = { state: 'PUBLISHED' };class DocumentProcess<State> {constructor(public readonly content: string) {}static create(content: string): DocumentProcess<Draft> {return new DocumentProcess<Draft>(content);}}function publishDocument(doc: DocumentProcess<Draft>): DocumentProcess<Published> {return new DocumentProcess<Published>(doc.content);}const draftDoc = DocumentProcess.create('Framework Core RFC');const publishedDoc = publishDocument(draftDoc);// publishDocument(publishedDoc); // Compile Error: Argument of type 'DocumentProcess<Published>' is not assignable to 'DocumentProcess<Draft>'
Breakdown
1
class DocumentProcess<State> {
Declares a class with a phantom generic parameter 'State' that exists strictly at compile time for type tracking.
2
static create(content: string): DocumentProcess<Draft>
Factory method instantiating the document workflow strictly bound to the initial 'Draft' state tag.
3
function publishDocument(doc: DocumentProcess<Draft>): DocumentProcess<Published>
Transition function accepting only 'Draft' state documents and yielding a new instance tagged as 'Published'.
4
// publishDocument(publishedDoc); // Compile Error
Demonstrates type checking preventing invalid re-publication operations prior to execution.