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:
| Property | Type | Description |
|---|---|---|
kind | 'MixinType' | Always 'MixinType'. |
name | string | undefined | Registry name. undefined for anonymous mixin types. |
description | string | undefined | Human-readable description. |
abstract | boolean | undefined | Whether the type is abstract. |
embedded | boolean | true when the type has no name. |
Properties inherited from ComplexTypeBase:
| Property | Type | Description |
|---|---|---|
keyField | string | undefined | Key field from the last constituent type that declares one. |
additionalFields | boolean | DataType | ['error'] | ['error', string] | undefined | Merged from constituent types — true if any constituent allows additional fields. |
ctor | Type | undefined | TypeScript class constructor. |
Properties on MixinType:
| Property | Type | Description |
|---|---|---|
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.
| Method | Description |
|---|---|
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