Skip to main content

MixinType

Package: @opra/common

MixinType is the runtime class that represents a type formed by merging the fields of two or more existing ComplexType, MappedType, or other MixinType instances. It is the runtime counterpart of the MixinType(...) factory function call.

A MixinType exposes the full field API of ComplexTypeBase — fields from all constituent types are merged into a flat field map, so you can iterate, look up, and generate codecs exactly as you would with a ComplexType.


Inheritance

DocumentElement
└── DataType
└── ComplexTypeBase ← shared field API (fields, findField, getField, …)
└── MixinType

Properties

Properties inherited from DataType:

PropertyTypeDescription
kind'MixinType'Always 'MixinType'.
namestring | undefinedRegistry name. undefined for anonymous mixin types.
descriptionstring | undefinedHuman-readable description.
abstractboolean | undefinedWhether the type is abstract.
embeddedbooleantrue when the type has no name.

Properties inherited from ComplexTypeBase:

PropertyTypeDescription
keyFieldstring | undefinedKey field from the last constituent type that declares one.
additionalFieldsboolean | DataType | ['error'] | ['error', string] | undefinedMerged from constituent types — true if any constituent allows additional fields.
ctorType | undefinedTypeScript class constructor.

Properties on MixinType:

PropertyTypeDescription
types(ComplexType | MixinType | MappedType)[]The constituent types merged into this mixin, in declaration order.

Field merging

Fields are merged from types in order. If two constituent types declare a field with the same name, the last one wins. additionalFields is set to true if any constituent type allows additional fields.


Field methods

All field methods are inherited from ComplexTypeBase and behave identically to ComplexType. See ComplexType — Field methods.

MethodDescription
findField(nameOrPath, scope?)Returns the ApiField at the given name/path, or undefined.
getField(nameOrPath, scope?)Same as findField but throws if not found.
fields(scope?)Iterator over all merged ApiField instances visible in scope.
fieldNames(scope?)Iterator over merged field names.
fieldEntries(scope?)Iterator over [name, ApiField] pairs.
fieldCount(scope?)Count of merged fields visible in scope.
parseFieldPath(path, options?)Resolves a dot-separated path to an array of ParsedFieldPath items.
normalizeFieldPath(path, options?)Resolves a path and returns its canonical dot-separated form.

Methods

extendsFrom(baseType)

Returns true if any of the constituent types (or their base chains) extend from the given type.

extendsFrom(baseType: DataType | string | Type | object): boolean
const mixinType = document.node.getDataType('PersonWithAddress');
if (mixinType instanceof MixinType) {
mixinType.extendsFrom('Person'); // true if Person is one of the constituents
mixinType.extendsFrom('Address'); // true if Address is one of the constituents
}

generateCodec(codec, options?)

Inherited from ComplexTypeBase. Compiles a codec that validates/transforms the merged field set of this mixin.

generateCodec(
codec: 'encode' | 'decode',
options?: DataType.GenerateCodecOptions
): Validator

toJSON(options?)

Returns an OpraSchema.MixinType plain object for schema export, including the types array (by name if registered, inline otherwise).

toJSON(options?: ApiDocument.ExportOptions): OpraSchema.MixinType

Creating a MixinType

Use the MixinType(types, options?) factory function call (without new) in your schema declarations:

import { ComplexType, ApiField, MixinType } from '@opra/common';

@ComplexType()
class Person {
@ApiField() declare givenName: string;
@ApiField() declare familyName: string;
}

@ComplexType()
class WithTimestamps {
@ApiField({ readonly: true }) declare createdAt: Date;
@ApiField({ readonly: true }) declare updatedAt: Date;
}

// Produces a class decorated with MixinType metadata
const PersonWithTimestamps = MixinType([Person, WithTimestamps]);

The result can be used as a base class, a request body type, or a response type.


Obtaining a MixinType instance

import { MixinType } from '@opra/common';

const type = document.node.getDataType('PersonWithTimestamps');

if (type instanceof MixinType) {
console.log(type.kind); // 'MixinType'
console.log(type.types.length); // 2
console.log(type.types[0].name); // 'Person'
console.log(type.types[1].name); // 'WithTimestamps'

for (const field of type.fields()) {
console.log(field.name); // givenName, familyName, createdAt, updatedAt
}
}

ApiDocument · ComplexType · MappedType