API Stability Notice

Macroforge is under active development. The API is not yet stable and may change between versions. Some documentation sections may be outdated.

Default

The Default macro generates a static defaultValue() factory method that creates instances with default values. This is analogous to Rust’s Default trait, providing a standard way to create “zero” or “empty” instances of types.

Generated Output

TypeGenerated CodeDescription
Classstatic defaultValue(): ClassNameStatic factory method
EnumdefaultValueEnumName(): EnumNameStandalone function returning marked variant
InterfacedefaultValueInterfaceName(): InterfaceNameStandalone function returning object literal
Type AliasdefaultValueTypeName(): TypeNameStandalone function with type-appropriate default

Default Values by Type

The macro uses Rust-like default semantics:

TypeDefault Value
string"" (empty string)
number0
booleanfalse
bigint0n
T[][] (empty array)
Array<T>[] (empty array)
Map<K,V>new Map()
Set<T>new Set()
Datenew Date() (current time)
T \| nullnull
CustomTypeCustomType.defaultValue() (recursive)

Field-Level Options

The @default decorator allows specifying explicit default values:

  • @default(42) - Use 42 as the default
  • @default("hello") - Use “hello” as the default
  • @default([]) - Use empty array as the default
  • @default({ value: "test" }) - Named form for complex values

Example

Before (Your Code)
/** @derive(Default) */
class UserSettings {
    /** @default("light") */
    theme: string;

    /** @default(10) */
    pageSize: number;

    notifications: boolean; // Uses type default: false
}
After (Generated)
class UserSettings {
    theme: string;

    pageSize: number;

    notifications: boolean; // Uses type default: false

    static defaultValue(): UserSettings {
        const instance = new UserSettings();
        instance.theme = 'light';
        instance.pageSize = 10;
        instance.notifications = false;
        return instance;
    }
}

Generated output:

class UserSettings {
    theme: string;

    pageSize: number;

    notifications: boolean; // Uses type default: false

    static defaultValue(): UserSettings {
        const instance = new UserSettings();
        instance.theme = 'light';
        instance.pageSize = 10;
        instance.notifications = false;
        return instance;
    }
}

Enum Defaults

For enums, mark one variant with @default:

Before (Your Code)
/** @derive(Default) */
enum Status {
    /** @default */
    Pending,
    Active,
    Completed
}
After (Generated)
enum Status {
    /** @default */
    Pending,
    Active,
    Completed
}

export function statusDefaultValue(): Status {
    return Status.Pending;
}

namespace Status {
    export const defaultValue = statusDefaultValue;
}

Generated output:

enum Status {
    /** @default */
    Pending,
    Active,
    Completed
}

export function statusDefaultValue(): Status {
    return Status.Pending;
}

namespace Status {
    export const defaultValue = statusDefaultValue;
}

Error Handling

The macro will return an error if:

  • A non-primitive field lacks @default and has no known default
  • An enum has no variant marked with @default
  • A union type has no @default on a variant