Skip to main content
xstate-typescript Covers TypeScript patterns for type-safe XState v5 machines. Use when setting up typed machines with setup(), typing context/events/input/output, using type-bound helpers (v5.22+), assertEvent(), or type helpers like ActorRefFrom and SnapshotFrom. Requires TypeScript 5.0+.
Zur Installation springen Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/IlyaGulya/claude-marketplace --skill xstate-typescriptDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Verwandte Berufe SOC
Basierend auf der SOC-Berufsklassifikation
name xstate-typescript description Covers TypeScript patterns for type-safe XState v5 machines. Use when setting up typed machines with setup(), typing context/events/input/output, using type-bound helpers (v5.22+), assertEvent(), or type helpers like ActorRefFrom and SnapshotFrom. Requires TypeScript 5.0+.
XState v5 TypeScript
Prerequisites
TypeScript 5.0+ (latest recommended)
strictNullChecks: true in tsconfig.json (strongly recommended)
skipLibCheck: true in tsconfig.json (recommended)
{
"compilerOptions" : {
"strictNullChecks" : true ,
"skipLibCheck" : true
}
}
The setup() Pattern
The setup() function is the primary way to create type-safe machines:
import { setup } from 'xstate' ;
const machine = setup ({
types : {
context : {} as {
: ;
: | ;
: | ;
},
: {}
| { : ; : }
| { : }
| { : },
: {} {
: ;
},
: {} {
: ;
},
: {} {
: ;
},
: {} | ,
},
: { },
: { },
: { },
: { },
}). ({
});
userId
string
data
User
null
error
string
null
events
as
type
'FETCH'
userId
string
type
'RETRY'
type
'RESET'
input
as
initialUserId
string
output
as
result
User
children
as
fetcher
'fetchUser'
tags
as
'loading'
'error'
actions
guards
actors
delays
createMachine
The {} as Type pattern is a TypeScript idiom for providing type information without runtime values.
Typing Context and Events const machine = setup ({
types : {
context : {} as {
count : number ;
items : string [];
user : { name : string ; email : string } | null ;
},
events : {} as
| { type : 'increment' ; value : number }
| { type : 'item.add' ; item : string }
| { type : 'item.remove' ; index : number }
| { type : 'user.set' ; user : { name : string ; email : string } },
},
}).createMachine ({
context : {
count : 0 ,
items : [],
user : null ,
},
on : {
increment : {
actions : assign ({
count : ({ context, event } ) => context.count + event.value ,
}),
},
'item.add' : {
actions : assign ({
items : ({ context, event } ) => [...context.items , event.item ],
}),
},
},
});
Typing Input and Output For reusable machines that accept configuration and produce results:
const searchMachine = setup ({
types : {
context : {} as {
query : string ;
results : SearchResult [];
},
input : {} as {
initialQuery : string ;
maxResults : number ;
},
output : {} as {
results : SearchResult [];
totalCount : number ;
},
},
}).createMachine ({
context : ({ input } ) => ({
query : input.initialQuery ,
results : [],
}),
states : {
done : {
type : 'final' ,
},
},
output : ({ context } ) => ({
results : context.results ,
totalCount : context.results .length ,
}),
});
const actor = createActor (searchMachine, {
input : { initialQuery : 'xstate' , maxResults : 10 },
});
Typing Actions and Guards
Parameterized Actions const machine = setup ({
actions : {
notify : (_, params : { message: string ; level: 'info' | 'error' } ) => {
showNotification (params.message , params.level );
},
},
guards : {
isAboveThreshold : (_, params : { value: number ; threshold: number } ) => {
return params.value > params.threshold ;
},
},
}).createMachine ({
on : {
SUCCESS : {
actions : {
type : 'notify' ,
params : { message : 'Done!' , level : 'info' },
},
},
CHECK : {
guard : {
type : 'isAboveThreshold' ,
params : ({ context } ) => ({
value : context.count ,
threshold : 100 ,
}),
},
},
},
});
Type-Bound Helpers (v5.22+) Create actions in separate files while maintaining full type safety:
import { setup } from 'xstate' ;
export const machineSetup = setup ({
types : {
context : {} as { count : number ; items : string [] },
events : {} as
| { type : 'increment' }
| { type : 'addItem' ; item : string }
| { type : 'reset' },
emitted : {} as { type : 'COUNT_CHANGED' ; count : number },
},
});
import { machineSetup } from './machineSetup' ;
export const incrementCount = machineSetup.assign ({
count : ({ context } ) => context.count + 1 ,
});
export const addItem = machineSetup.assign ({
items : ({ context, event } ) => [...context.items , event.item ],
});
export const raiseReset = machineSetup.raise ({ type : 'reset' });
export const emitChange = machineSetup.emit (({ context } ) => ({
type : 'COUNT_CHANGED' ,
count : context.count ,
}));
export const logState = machineSetup.createAction (({ context, event } ) => {
console .log ("Count: " + context.count + ", Event: " + event.type );
});
import { machineSetup } from './machineSetup' ;
import { incrementCount, addItem, logState } from './actions' ;
export const machine = machineSetup.createMachine ({
context : { count : 0 , items : [] },
initial : 'active' ,
states : {
active : {
entry : logState,
on : {
increment : { actions : incrementCount },
addItem : { actions : addItem },
},
},
},
});
Modular State Configs (v5.21+) Split large machines across files with createStateConfig():
export const appSetup = setup ({
types : {
context : {} as AppContext ,
events : {} as AppEvent ,
},
actions : { },
actors : { },
});
import { appSetup } from '../setup' ;
export const editingState = appSetup.createStateConfig ({
entry : { type : 'loadDraft' },
on : {
SAVE : { target : 'saving' , actions : { type : 'saveDraft' } },
VALIDATE : { target : 'validating' },
},
});
import { appSetup } from './setup' ;
import { editingState } from './states/editing' ;
export const appMachine = appSetup.createMachine ({
initial : 'editing' ,
states : {
editing : editingState,
validating : { },
saving : { },
},
});
Type Helpers
ActorRefFrom Get a typed actor reference from actor logic:
import { type ActorRefFrom } from 'xstate' ;
type MyActorRef = ActorRefFrom <typeof myMachine>;
interface Props {
actorRef : ActorRefFrom <typeof formMachine>;
}
SnapshotFrom Get a typed snapshot from actor logic or actor ref:
import { type SnapshotFrom } from 'xstate' ;
type MySnapshot = SnapshotFrom <typeof myMachine>;
function renderState (snapshot : SnapshotFrom <typeof myMachine> ) {
snapshot.context ;
snapshot.value ;
}
EventFromLogic Get all event types from actor logic:
import { type EventFromLogic } from 'xstate' ;
type MyEvent = EventFromLogic <typeof myMachine>;
OutputFrom Get the output type from actor logic:
import { type OutputFrom } from 'xstate' ;
type MyOutput = OutputFrom <typeof myMachine>;
assertEvent() Narrow event types in actions/guards where the event type is a union:
import { assertEvent } from 'xstate' ;
const machine = setup ({
types : {
events : {} as
| { type : 'greet' ; name : string }
| { type : 'submit' ; data : FormData }
| { type : 'cancel' },
},
}).createMachine ({
states : {
greeting : {
entry : ({ event } ) => {
assertEvent (event, 'greet' );
console .log (event.name .toUpperCase ());
},
},
processing : {
exit : ({ event } ) => {
assertEvent (event, ['greet' , 'submit' ]);
},
},
},
});
Prefer dynamic params over assertEvent — params are more reusable:
actions : {
greetUser : (_, params : { name: string } ) => {
console .log ("Hello, " + params.name + "!" );
},
}
Common Patterns
Typing fromPromise import { fromPromise } from 'xstate' ;
interface User { id : string ; name : string }
const fetchUser = fromPromise<User , { userId : string }>(async ({ input }) => {
const res = await fetch (`/api/users/${input.userId} ` );
return res.json () as Promise <User >;
});
invoke : {
src : 'fetchUser' ,
input : ({ context } ) => ({ userId : context.userId }),
onDone : {
actions : assign ({
user : ({ event } ) => event.output ,
}),
},
}
Typing .provide()
const testMachine = machine.provide ({
actions : {
notify : (_, params : { message: string ; level: 'info' | 'error' } ) => {
console .log (params.message );
},
},
actors : {
fetchUser : fromPromise<User , { userId : string }>(async ({ input }) => {
return mockUser;
}),
},
});
Context Factory with Input const machine = setup ({
types : {
context : {} as {
userId : string ;
preferences : UserPrefs ;
isReady : boolean ;
},
input : {} as {
userId : string ;
preferences ?: Partial <UserPrefs >;
},
},
}).createMachine ({
context : ({ input } ) => ({
userId : input.userId ,
preferences : {
theme : 'light' ,
language : 'en' ,
...input.preferences ,
},
isReady : false ,
}),
});
Mehr aus diesem Repository Build frontend interfaces with externally randomized style direction. Use when the user asks to build web components, pages, or applications with high design diversity. Produces distinctive, production-grade UI that avoids repetitive AI aesthetics.
Analyzes CLAUDE.md, AGENTS.md, and similar repository context files for effectiveness based on peer-reviewed research. Identifies instructions that hurt agent performance, redundant content, and unnecessary requirements. Use when reviewing a CLAUDE.md, auditing an AGENTS.md, optimizing context files, or when the user says "lint my CLAUDE.md", "review my AGENTS.md", "is my context file good", "optimize my context file", or "check my CLAUDE.md".
skill-creator-frontmatter Complete reference for Claude Code skill YAML frontmatter fields, their values, and best practices. Use when writing frontmatter for SKILL.md, configuring skill invocation, setting allowed-tools, or deciding on skill metadata fields.