Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Record types

Record types {} are simple property records.

Specifically, there are variations of the record type, which are each represented and used in a different way.

map {} types are like a hash-map internally, using boxing for primitive types. Fields that are not specified are not inserted into the structure.

type Options = map {
    quack? : uint,
    shot? : boolean,
};

tap {} types are similar to map {}, but their creation and field accessors are implementation-defined, and they desugar to classes.

Although map {} and tap {} types appear as type expressions, they are unique; structurally-matching records cannot be assigned to the other, or vice versa.

Version control

Fields of a record type may be tied to a namespace, which is useful for version control.

Flexible.sx

package zero.hit {
    public namespace Flexible = "http://www.zero.org/hit/Flexible";
}

Judgement.sx

package zero.hit {
    public namespace Judgement = "http://www.zero.org/hit/Judgement";
}

Pair.sx

package zero.hit {
    public type Information = map {
        Flexible::strength : [decimal],
        Judgement::strength : [decimal],
    };
}

Field omission

A field is required to be initialized in object literals unless it contains undefined. A field such as x? : T is equivalent to x : (void, T).

A field containing null but not undefined must be initialized.

Field order

Due to sensitive field order, record types with equivalent fields but in different orders will be incompatible.

Writing ShockDoc comments

Fields may have a preceding ShockDoc comment, as in:

type R = map {
    /**
     * Comment.
     */
    x : double,
};

Compatibility

Two record types are compatible only if either:

  • One is used as a subset of another
  • Fields are equivalent, appear in the same order and include no ShockDoc.

Rest

One trailing ...rest component may appear in a record, where rest must be another record type. The resulting type is a subtype of rest and properties must not collide.

// A
type A = map { x : double };
// B < A
type B = map { y : double, ...A };

β€œtap {}”

tap {} types desugar into classes dedicated to reactive systems like Whack DS, typically for representing UI component properties.

type Props = tap {
    x? : double,
}
  • In Whack DS, when the x property of the above Props type is accessed, the x property is auto tracked as a dependency of the surrounding effect or callback.
  • A tap {} type in Whack DS uses a hash map for storing props internally, since components use to define several properties, including several event handlers, which are not always specified by the consumer.