interface Slabbable { readonly byteSize: number; readonly byteAlignment: number; new (buffer: SharedArrayBuffer, byteOffset: number): T; } type SlabInstances[]> = { [K in keyof T]: T[K] extends Slabbable ? I : never; }; function align(offset: number, alignment: number): number { const remainder = offset % alignment; return remainder === 0 ? offset : offset + (alignment - remainder); } export function slab[]>(...classes: T): SlabInstances { const offsets: number[] = []; let cursor = 0; for (const cls of classes) { cursor = align(cursor, cls.byteAlignment); offsets.push(cursor); cursor += cls.byteSize; } const buffer = new SharedArrayBuffer(cursor); const instances = classes.map((cls, i) => new cls(buffer, offsets[i])); return instances as SlabInstances; }