Skip to content

Spawn typed

A Behavior<T> is a value. To put it into the runtime — to get an actual ActorRef<T> you can tell messages to — use one of three helpers:

HelperSpawn targetCaller
spawnTyped(system, behavior, name?)Top-level actor under /user.Outside an actor.
spawnTypedChild(ctx, behavior, name?)Child of an untyped actor.Inside an untyped Actor.onReceive.
typedProps(behavior)Props<T>Anywhere Props is accepted.When you want to plug a Behavior into APIs that take Props.

For typed-actor-to-typed-child spawning, use the ctx.spawn(...) method on TypedActorContext instead — covered below.

import { ActorSystem, Behaviors, spawnTyped } from 'actor-ts';
type Cmd = { kind: 'inc' } | { kind: 'get'; replyTo: ActorRef<number> };
const counter = (n: number): Behavior<Cmd> => Behaviors.receive((ctx, cmd) => {
if (cmd.kind === 'inc') return counter(n + 1);
if (cmd.kind === 'get') { cmd.replyTo.tell(n); return Behaviors.same; }
return Behaviors.same;
});
const system = ActorSystem.create('demo');
const ref = spawnTyped(system, counter(0), 'counter');
// ^- ActorRef<Cmd>

The signature:

function spawnTyped<T>(
system: ActorSystem,
behavior: Behavior<T>,
name?: string,
): ActorRef<T>;

Returns a typed ActorRef<T>tell accepts only Cmd-shaped messages, the compiler enforces it.

spawnTypedChild — typed child from an untyped parent

Section titled “spawnTypedChild — typed child from an untyped parent”
import { Actor, type ActorContext, Behaviors, spawnTypedChild } from 'actor-ts';
class UntypedParent extends Actor<...> {
override preStart(): void {
const typedChild = spawnTypedChild(this.context, counter(0), 'child');
// typedChild: ActorRef<Cmd>
typedChild.tell({ kind: 'inc' });
}
}

The signature:

function spawnTypedChild<T>(
ctx: ActorContext,
behavior: Behavior<T>,
name?: string,
): ActorRef<T>;

Useful when you have an existing untyped supervisor that needs to spawn typed workers. The child is a normal entry in the parent’s children list — supervisor strategies apply per the parent’s strategy, death watch works both ways.

import { typedProps } from 'actor-ts';
const props = typedProps(counter(0))
.withMailboxCapacity(500)
.withDispatcher(myDispatcher);
const ref = system.actorOf(props, 'counter');

When you want a typed Behavior but the API takes Props<T> (because it’s an older entry point, or because you want to chain with… builders), typedProps(behavior) returns the right Props<T>.

The shape:

function typedProps<T>(behavior: Behavior<T>): Props<T>;

The returned Props can be passed anywhere Props<T> is expected — system.actorOf, context.actorOf, Cluster.singletonProxy, the sharding region’s entity-props slot.

Inside a typed handler, the context exposes its own spawn:

const parent: Behavior<ParentMsg> = Behaviors.setup((ctx) => {
const child = ctx.spawn(workerBehavior, 'worker');
// ^- ActorRef<WorkerMsg>
return Behaviors.receive((ctx, msg) => {
child.tell({ kind: 'do-it' });
return Behaviors.same;
});
});

This is the standard way for typed parents to spawn typed children. Same semantics as spawnTypedChild from the untyped side, but typed all the way through — ctx.spawn(behavior) knows the child’s message type from the Behavior’s type parameter.

No spawnTyped import needed inside typed code; the context provides it.

The name parameter is optional in all four entry points:

  • Omit it → framework generates one ('$1', '$2', …).
  • Provide it → must be unique among siblings.

The resulting actor’s path follows the standard format:

  • spawnTyped(system, b, 'counter')actor-ts://my-app/user/counter
  • spawnTypedChild(parentCtx, b, 'worker')actor-ts://my-app/user/<parent>/worker
  • ctx.spawn(b, 'worker')actor-ts://my-app/user/<parent>/worker

See Actor paths for the path semantics.

Caller is outside an actor:
→ spawnTyped(system, b, name)
Caller is inside an untyped Actor.onReceive:
→ spawnTypedChild(this.context, b, name)
Caller is inside a typed Behaviors.setup or handler:
→ ctx.spawn(b, name)
You have a function that takes Props<T> and you want to use a Behavior:
→ typedProps(b)

The three helpers are deliberately small — each handles one common case. typedProps is the escape hatch when you need to plug a behavior into Props-shaped APIs.

  • Behaviors — the DSL that produces the values you pass to these helpers.
  • Typed actor — the runtime that all four helpers wrap.
  • Props — the untyped configuration typedProps returns.
  • Actor system — the actorOf API the helpers ultimately call.