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