Forger Help

Inheritance and Generics

Forger resolves types through the TypeScript checker, so inheritance chains and generic substitutions work the way the compiler sees them.

Inheritance

The whole chain is flattened: properties of every ancestor are merged with the properties of the type itself.

interface BaseEntity { id: number; createdAt: Date; } interface Employee extends BaseEntity { name: string; } const employee = Forger.create<Employee>()!; // { id: 952, createdAt: Date(…), name: '…' } — id and createdAt included

The same applies to extends in classes and to interface-to-class inheritance.

Generics

Generic arguments are substituted at the call site: Box<number> is resolved as if T were replaced with number everywhere in the declaration.

interface Box<T> { content: T; label: string; } const box = Forger.create<Box<number>>()!; // { content: 452, label: '…' } const stringBox = Forger.create<Box<string>>()!; // { content: '…', label: '…' }

Multiple type arguments work the same way:

interface Pair<A, B> { first: A; second: B; } const pair = Forger.create<Pair<string, Date>>()!; // { first: '…', second: Date(…) }

Generic types nested inside other types (Box<Box<number>>) are resolved recursively.

Inherited generics

A generic type that inherits from another generic resolves after substitution:

interface Entity<T> { id: T } interface User extends Entity<number> { name: string } const user = Forger.create<User>()!; // { id: 417, name: '…' } — id is a number, exactly as Entity<number> declares

Union type arguments

Type arguments may themselves be unions or literal unions — they follow the regular union rules:

const settings = Forger.create<Box<'on' | 'off'>>()!; // { content: 'on', label: '…' } — or 'off', rolled at runtime
08 September 2026