IoStruct
On this page

IoStruct

Interface in Layout

The handle ioStruct returns: a struct that crosses a stage boundary, whose fields carry @builtin or @location attributes.

import type { IoStruct } from 'typeshade'

The signature, the description and the examples come from the compiler's own source at commit 26de7be8.

Syntax

interface IoStruct<F extends Record<string, FieldSpec>, N extends string = string> {
readonly decl: StructDecl;
readonly type: { readonly kind: 'struct'; readonly name: N };
of(node: Node): { readonly [K in keyof F]-?: Node<KeyOf<NonNullable<F[K]>['type']>> } & { readonly $: ReadonlyNode<`struct:${N}`>; };
of(node: ReadonlyNode): { readonly [K in keyof F]-?: ReadonlyNode<KeyOf<NonNullable<F[K]>['type']>>; } & { readonly $: ReadonlyNode<`struct:${N}`>; };
var(name?: string): { readonly [K in keyof F]-?: Node<KeyOf<NonNullable<F[K]>['type']>> } & { readonly $: ReadonlyNode<`struct:${N}`>; };
construct(values: { readonly [K in keyof F]: ReadonlyNode<KeyOf<NonNullable<F[K]>['type']>>; }): Node<`struct:${N}`>;
}

Description

The handle ioStruct returns: a struct that crosses a stage boundary (a vertex output, a fragment input, a compute IO record), whose fields carry @builtin or @location attributes. It bundles the StructDecl for module({ structs }), the struct’s ShaderType, a typed field-read proxy for any node of this shape, and a one-expression constructor. Use PlainStruct for a struct that never crosses a stage boundary (a storage-buffer element, a nested struct); its fields carry no attribute, which is the only difference between the two.

Instance properties

declread only StructDecl

The struct declaration, for module({ structs }).

typeread only { readonly kind: 'struct'; readonly name: N }

The struct’s ShaderType, carrying the name as a literal so every value built from this handle has the exact struct:${N} key typeKey produces.

Instance methods

of (node: Node): { readonly [K in keyof F]-?: Node<KeyOf<NonNullable<F[K]>['type']>> } & { readonly $: ReadonlyNode<`struct:${N}`>; }

Typed field access on a value of this struct: VsOut.of(node).uv is the same member read as member(node, 'uv', <its type>), with the field name and type checked. The view’s write capability follows the base: a mutable base (a Var) gives Node fields, which accept .assign(...); a read-only base (a parameter, a Let) gives ReadonlyNode fields. .$ is the raw struct value. A field spread in conditionally (...(cond ? { pick } : {})) is typed as present, so optional output fields stay plain.

of (node: ReadonlyNode): { readonly [K in keyof F]-?: ReadonlyNode<KeyOf<NonNullable<F[K]>['type']>>; } & { readonly $: ReadonlyNode<`struct:${N}`>; }
var (name?: string): { readonly [K in keyof F]-?: Node<KeyOf<NonNullable<F[K]>['type']>> } & { readonly $: ReadonlyNode<`struct:${N}`>; }

Declare a var of this struct and return its typed field proxy in one step: const o = VsOut.var(). Assign fields with o.uv.assign(...) and return or forward the raw value with o.$. name pins the emitted WGSL identifier.

construct (values: { readonly [K in keyof F]: ReadonlyNode<KeyOf<NonNullable<F[K]>['type']>>; }): Node<`struct:${N}`>

Build a value of this struct in one expression, keyed by field name. Values are placed in field-declaration order, and a missing or wrong field is a tsc error.

See also

Source

src/core/sot.ts, line 338, at commit 26de7be8

Edit this page Report a problem