Import
import { Renderable } from "@typed/template";Signatures
export type Renderable<A, E = never, R = never> = A | {
readonly [key: string]: Renderable<unknown, E, R>;
} | ReadonlyArray<Renderable<A, E, R>> | Effect.Effect<A, E, R> | Stream.Stream<A, E, R> | Fx.Fx<A, E, R> | HydrationRef<E, R> | ([
A
] extends [
ReadonlyArray<infer Item>
] ? Many<Item, E, R> : never);export declare namespace Renderable {
type Any<A = any> = Renderable<A, any, any> | Renderable<A, never, never> | Renderable<never, any, any> | Renderable<never, never, any>;
type Primitive = string | number | boolean | bigint | null | undefined | void | RenderEvent;
type Effects = Effect.Effect<any, any, any> | Fx.Fx<any, any, any> | Stream.Stream<any, any, any>;
type Services<T> = RenderableServices<T>;
type Error<T> = RenderableError<T>;
type Success<T> = [
T
] extends [
never
] ? never : T extends Many<infer A, any, any> ? ReadonlyArray<A> : T extends Fx.Fx<infer A, any, any> ? A : T extends Stream.Stream<infer A, any, any> ? A : T extends Effect.Effect<infer A, any, any> ? Success<A> : T extends Option.Option<infer A> ? Success<A> | null : T extends ReadonlyArray<any> ? {
readonly [K in keyof T]: Success<T[K]>;
} : T extends null | undefined | void ? null : T extends (...args: Array<any>) => any ? null : T extends RenderEvent ? T : T extends object ? {
readonly [K in keyof T]: Success<T[K]>;
} : T;
type ServicesFromObject<T> = [
{
[K in keyof T]-?: T[K] extends (...args: Array<any>) => any ? FunctionServices<ReturnType<T[K]>> : Services<T[K]>;
}[keyof T]
] extends [
infer U
] ? U : never;
type ErrorFromObject<T> = [
{
[K in keyof T]-?: T[K] extends (...args: Array<any>) => any ? FunctionError<ReturnType<T[K]>> : Error<T[K]>;
}[keyof T]
] extends [
infer U
] ? U : never;
}Why
Renderable is deliberately a union of Effect ecosystem values and ordinary
data rather than a component base class. Effect, Stream, Fx, hydration refs,
arrays, objects, primitives, and RenderEvent outputs preserve their own
success, error, and service channels through template inference.
Ownership and lifetime
A Renderable is a description or borrowed value. Calling html does not run
it; the Scope that drains the resulting Fx owns upstream subscriptions,
interruption, and finalizers. Existing DOM nodes retain their identity and
external owner until inserted into a renderer-owned dynamic range.
Examples
import { Effect } from "effect"
import { html } from "@typed/template"
import { Fx } from "@typed/fx"
import { RefSubject } from "@typed/fx/RefSubject"
// Primitives
const primitive = html`<div>${"Hello"}</div>`
const number = html`<div>${42}</div>`
const boolean = html`<div>${true}</div>`
// Effects
const effect = html`<div>${Effect.succeed("Async value")}</div>`
// Fx streams (reactive)
const program = Effect.gen(function* () {
const count = yield* RefSubject.make(0)
return html`<div>Count: ${count}</div>`
})
// Arrays
const items = [1, 2, 3]
const list = html`<ul>${items.map((n) => html`<li>${n}</li>`)}</ul>`
// Objects (for attributes)
const withProps = html`<div .data=${{ foo: "bar" }}></div>`Members
Renderable.AnyA type alias for any Renderable value with any error/context.
Renderable.EffectsThe Effect ecosystem producers recognized as reactive Renderables.
Renderable.ErrorExtracts the error type from a Renderable type.
Renderable.ErrorFromObjectTraverse all keys in an object and extract the error from each value. If the value is a function, extract the error from the return type of the function.
Renderable.PrimitiveThe basic primitive types that can be rendered directly.
Renderable.ServicesExtracts the required services from a Renderable type.
Renderable.ServicesFromObjectTraverse all keys in an object and extract the services from each value. If the value is a function, extract the services from the return type of the function.
Renderable.SuccessRecursively computes the terminal value emitted by a Renderable.
Other public imports
These import paths expose the same declaration. Each page retains its own public name and signature.