Typed messages API
The self-rendering Message object: mutable and immutable builders, the init and envelope shapes, the factory the dict packages re-export, and the type guard for narrowing at boundaries. Generated from @boarteam/fix 0.5.2 as installed; the doc text is the library’s own. Guide: Typed messages.
createMessagefunctionsince 0.3.0
function createMessage<B extends object = UntypedBody>(msgType: string, dict: Dictionary | DictionaryJSON, init?: MessageInit<B>): MutableMessage<B>Source: packages/fix/src/message.ts:408
Create a MutableMessage for a MsgType, optionally seeded with a complete MessageInit (omit it to build incrementally). The body type B defaults to the loose UntypedBody; pass a generated per-message body type (or use the dict package's typed message factory / a createFixEngine<Bodies> engine) for field-level type safety.
| Parameter | Type | Description |
|---|---|---|
| msgType | string | The MsgType (tag 35) value the message is created for. |
| dict | Dictionary | DictionaryJSON | The dictionary that defines the message and renders it. |
| init? | MessageInit<B> | Optional complete body init (see MessageInit); omit to build incrementally. |
Returns MutableMessage<B> — A mutable, fluent builder typed to B.
createImmutableMessagefunctionsince 0.3.0
function createImmutableMessage<B extends object = UntypedBody>(msgType: string, dict: Dictionary | DictionaryJSON, init?: MessageInit<B>): ImmutableMessage<B>Source: packages/fix/src/message.ts:424
Create an ImmutableMessage for a MsgType. See createMessage.
| Parameter | Type | Description |
|---|---|---|
| msgType | string | The MsgType (tag 35) value the message is created for. |
| dict | Dictionary | DictionaryJSON | The dictionary that defines the message and renders it. |
| init? | MessageInit<B> | Optional complete body init (see MessageInit); omit to build incrementally. |
Returns ImmutableMessage<B> — An immutable message; every edit returns a new instance.
messageFactoryfunctionsince 0.3.0
function messageFactory<Bodies>(dict: Dictionary | DictionaryJSON): MessageFactory<Bodies>Source: packages/fix/src/message.ts:445
Build a dictionary-bound MessageFactory typed by a Bodies registry (the generated MessageBodies map of MsgType value → body type). The dict packages call this and re-export the result as message:
export const message = messageFactory<MessageBodies>(dictionary);message('W').set('MDReqID', 'r1'); // typed to MarketDataSnapshotFullRefreshmessage.immutable(MsgType.Logon).with(...);| Parameter | Type | Description |
|---|---|---|
| dict | Dictionary | DictionaryJSON | The dictionary every created message is bound to. |
Returns MessageFactory<Bodies> — The typed factory the dict packages re-export as message.
MessageFactoryinterfacesince 0.3.0
interface MessageFactory<Bodies>Source: packages/fix/src/message.ts:166
A dictionary-bound, typed message factory — the strongly-typed entry point the dict packages re-export (message). Call it with a MsgType value keyed into Bodies (e.g. MsgType.MarketDataSnapshotFullRefresh, the literal "W") to get a builder typed to exactly that message's body. Build one with messageFactory.
<M extends keyof Bodies & string>(msgType: M, init?: MessageInit<Bodies[M] & object>): MutableMessage<Bodies[M] & object>Create a mutable message for
msgType, optionally seeded with a completeinit(seeMessageInit: required keys must be named,undefineddeliberately omits; omitinitentirely to build incrementally).immutable<M extends keyof Bodies & string>(msgType: M, init?: MessageInit<Bodies[M] & object>): ImmutableMessage<Bodies[M] & object>Create an immutable message for
msgType, optionally seeded with a completeinit.
MessageViewinterfacesince 0.3.0
interface MessageView<B extends object>Source: packages/fix/src/message.ts:98
The read surface shared by the mutable and immutable Message — enough to drive log metadata (msgType, Symbol, SecurityID, per-entry prices) and to render to wire.
readonly msgType: stringThe
MsgType(tag 35) value this message was created for.get<K extends keyof B & string>(name: K): B[K] | undefinedRead a body field/group by name;
undefinedwhen unset. Typed to the field's value type.has(name: keyof B & string): booleanWhether a body field/group is currently renderable (not
undefined/null/'').toEncodeMessage(): EncodeMessageThe tag-keyed
EncodeMessagethis body renders to (the escape hatch to the low-levelencodeprimitive). Framing/envelope fields are not included — they are supplied torender.toJSON(): Partial<MessageInit<B>>A shallow snapshot of the name-keyed body as stored, absent values included (also used by
JSON.stringify).render(envelope?: Envelope, options?: EncodeOptions): stringRender to a complete, framed FIX string. The body is merged with the supplied
Envelopeand passed toencode: fields land in their dictionary-prescribed positions (envelope fields in the header, body fields in the body), so the output is byte-identical toencodeof equivalent content. On a tag collision the body value wins over the envelope.
MutableMessageinterfacesince 0.3.0
interface MutableMessage<B extends object>Source: packages/fix/src/message.ts:129
A mutable, fluent Message builder — the fast path for hot loops (per-tick market-data snapshots): set/assign mutate in place and return this for chaining, then MessageView.render converts the body once. Bodies are plain objects (no JS accessor properties), so writes are ordinary property assignments.
set<K extends keyof B & string>(name: K, value: FieldInit<B[K]> | null | undefined): thisSet one field/group (absent values allowed — see
MessageInit); returnsthisfor chaining.assign(fields: Partial<MessageInit<B>>): thisSet many fields/groups at once from a partial init object; returns
this.delete(name: keyof B & string): thisUnset a field/group; returns
this.toImmutable(): ImmutableMessage<B>A snapshot copy as an
ImmutableMessage(the mutable original is unaffected).
ImmutableMessageinterfacesince 0.3.0
interface ImmutableMessage<B extends object>Source: packages/fix/src/message.ts:146
An immutable Message — every edit returns a NEW instance (copy-on-write of the top-level body), leaving the original untouched. Preferred when a message is shared, cached, or treated as a value; use MutableMessage for the hot path. Copy-on-write is shallow: to change a repeating group, pass a fresh array to with/merge.
with<K extends keyof B & string>(name: K, value: FieldInit<B[K]> | null | undefined): ImmutableMessage<B>A new message with one field/group set (absent values allowed — see
MessageInit).merge(fields: Partial<MessageInit<B>>): ImmutableMessage<B>A new message with many fields/groups set from a partial init object.
without(name: keyof B & string): ImmutableMessage<B>A new message with a field/group unset.
toMutable(): MutableMessage<B>A snapshot copy as a
MutableMessage.
MessageInittypesince 0.4.0
type MessageInit<B> = { [K in keyof B]: FieldInit<B[K]> | null | undefined;}Source: packages/fix/src/message.ts:64
The init shape for a message body B — what MessageFactory, createMessage, and the engine's create accept. Key modifiers are preserved from B: a dictionary-required field must be named (pass undefined to deliberately omit it — the escape hatch for dialects that skip a "required" tag), an optional field may be left out entirely. Every value additionally accepts null | undefined, and all absent values — undefined, null, and '' — are skipped at render and reported absent by MessageView.has, so possibly-empty values pass straight through without guards:
message(MsgType.Logon, { EncryptMethod: EncryptMethod.NONE, HeartBtInt: 30, Username: username, // string | null | undefined — no `if (username)` needed Password: password,});Repeating-group entry arrays are widened deep via FieldInit: entry keys keep their requiredness, entry values accept the same absent forms. | undefined is spelled explicitly so the shape stays correct for consumers compiling with exactOptionalPropertyTypes.
FieldInittypesince 0.4.0
type FieldInit<V> = V extends readonly (infer E extends object)[] ? readonly MessageInit<E>[] : VSource: packages/fix/src/message.ts:74
A single field/group value in init position: a group-counter value (an array of entry bodies) is accepted as a readonly array of MessageInit-widened entries; scalar values pass through unchanged, so enum unions and dialect casts are preserved. Entries themselves may NOT be null/undefined — the renderer recurses into each entry object.
Envelopeinterfacesince 0.3.0
interface EnvelopeSource: packages/fix/src/message.ts:87
Envelope (header/trailer/session) fields supplied to MessageView.render at call time — the fields a Message deliberately does NOT model in its typed body: MsgSeqNum (34), SenderCompID (49), SendingTime (52), TargetCompID (56), and any other standard-header/trailer field. Keys may be field names (SenderCompID) or numeric tags (49); framing tags 8/9/10 and MsgType (35) are computed by the encoder and ignored if supplied here. Absent values (undefined, null, '') are skipped, so conditional session fields (SenderSubID, …) can be passed straight through.
readonly [field: string]: FieldValue | null | undefinedA header/trailer field addressed by its spec NAME, e.g.
SenderCompID.readonly [tag: number]: FieldValue | null | undefinedThe same field addressed by its numeric TAG, e.g.
49.
UntypedBodytypesince 0.3.0
type UntypedBody = Record<string, FieldValue | readonly UntypedBody[]>Source: packages/fix/src/message.ts:39
The loose body type for the untyped path: any field name maps to any scalar value or, for a group counter name, an array of entry bodies. Used as the default body type of createMessage/createFixEngine when no generated MessageBodies is supplied, so engine.create(someMsgType) still works — without the field-level type safety a concrete body type provides.
messageTypeGuardfunctionsince 0.3.0
function messageTypeGuard<Bodies>(): MessageTypeGuard<Bodies>Source: packages/fix/src/message.ts:508
Build a dictionary-agnostic MessageTypeGuard bound to a Bodies registry (the generated MessageBodies map of MsgType value → body type). The dict packages call this and re-export the result as isMessageType:
const isMessageType = messageTypeGuard<MessageBodies>();if (isMessageType(message, 'W')) { message.get('SecurityID'); // string | undefined — typed to MarketDataSnapshotFullRefresh message.get('NoMDEntries'); // the typed entry array}Pure and side-effect-free: the only runtime work is message.msgType === msgType, so it holds no dictionary, session, or transport state.
Returns MessageTypeGuard<Bodies> — The narrowing guard; its runtime is a plain msgType compare.
MessageTypeGuardtypesince 0.3.0
type MessageTypeGuard<Bodies> = <M extends keyof Bodies & string>(message: MessageView<any>, msgType: M) => message is MessageView<Bodies[M] & object>Source: packages/fix/src/message.ts:475
A Bodies-bound message-narrowing type guard — the read-side counterpart of MessageFactory. Given a message of unknown body (a MessageView<any>, e.g. at a generic send(message) boundary where the concrete msgType is erased) and a MsgType value keyed into Bodies, it narrows the message to that message's body so subsequent MessageView.get/MessageView.has reads are typed — no any, no casts. The runtime is a plain msgType string compare; the narrowing comes entirely from Bodies[M].
It narrows to the read surface MessageView (the interface both MutableMessage and ImmutableMessage extend), not to the mutable/immutable kind: the guard's job is typed reads at an inbound/outbound boundary, and a call site that already holds a concrete builder rarely needs to re-narrow it. Preserving the kind would take a second overload keyed on the input type for no read-side benefit. Build one with messageTypeGuard.
MessageOftypesince 0.3.0
type MessageOf<Bodies, M extends keyof Bodies & string> = MessageView<Bodies[M] & object>Source: packages/fix/src/message.ts:489
The read surface of the message whose MsgType value is M in a Bodies registry — a convenience alias for annotating a narrowed message (a function parameter, a variable). Equal to MessageView<Bodies[M] & object>; the dict packages emit a pre-bound one-argument MessageOf<M> over their generated MessageBodies.