ComplexType
Package: @opra/common
ComplexType is the runtime class that represents an object type in an OPRA document. When you retrieve a type from an ApiDocument via document.node.getDataType(), the returned instance is a ComplexType (or one of its siblings). You interact with it to inspect fields, traverse inheritance, generate codecs, and export schema.
The @ComplexType() decorator (used on TypeScript classes) is documented in the HTTP API and Schema sections — this page covers the class itself.
Inheritance
DocumentElement
└── DataType
└── ComplexTypeBase
└── ComplexType
ComplexTypeBase holds all field-related methods and is also the base of MappedType and MixinType. ComplexType adds the base reference, discriminator fields, and the extendsFrom() check.
Properties
Properties inherited from DataType:
| Property | Type | Description |
|---|---|---|
kind | 'ComplexType' | Always 'ComplexType'. |
name | string | undefined | Registry name. undefined for embedded (anonymous) types. |
description | string | undefined | Human-readable description. |
abstract | boolean | undefined | Whether the type is abstract. |
embedded | boolean | true when the type has no name. |
scopePattern | (string | RegExp)[] | undefined | Scopes this type is visible in. |
examples | DataTypeExample[] | undefined | Example values. |
owner | DocumentElement | The document element that owns this type. |
node | ApiDocumentNode | The root document node (used for type lookup). |
Properties on ComplexTypeBase:
| Property | Type | Description |
|---|---|---|
keyField | string | undefined | Name of the primary key field. |
additionalFields | boolean | DataType | ['error'] | ['error', string] | undefined | How undeclared fields are handled during validation. |
ctor | Type | undefined | The TypeScript class constructor registered for this type. |
Properties on ComplexType:
| Property | Type | Description |
|---|---|---|
base | ComplexType | MappedType | MixinType | undefined | The base type this type extends. |
discriminatorField | string | undefined | Field used to discriminate subtypes. |
discriminatorValue | string | undefined | This type's discriminator value. |
Field methods
All field methods are defined on ComplexTypeBase and inherited by ComplexType.
findField(nameOrPath, scope?)
Returns the ApiField at the given name or dot-separated path, or undefined if not found. Respects scope filtering.
const field = customerType.findField('address.city');
const field = customerType.findField('email', 'admin'); // only returns the field if it is visible in the 'admin' scope
findField(nameOrPath: string, scope?: string | '*'): ApiField | undefined
getField(nameOrPath, scope?)
Same as findField but throws if the field does not exist or is out of scope.
getField(nameOrPath: string, scope?: string): ApiField
fields(scope?)
Returns an iterator over all ApiField instances visible in the given scope. Pass '*' to include all fields regardless of scope.
for (const field of customerType.fields()) {
console.log(field.name, field.type.name);
}
// All fields, ignoring scope
for (const field of customerType.fields('*')) { }
fields(scope?: string): IterableIterator<ApiField>
fieldNames(scope?)
Returns an iterator over field names only.
fieldNames(scope?: string): IterableIterator<string>
fieldEntries(scope?)
Returns an iterator over [name, ApiField] pairs.
fieldEntries(scope?: string): IterableIterator<[string, ApiField]>
fieldCount(scope?)
Returns the number of fields visible in the given scope.
fieldCount(scope?: string): number
Inheritance methods
extendsFrom(baseType)
Returns true if this type extends from the given type (directly or transitively).
customerType.extendsFrom(Person) // true if Customer extends Person
customerType.extendsFrom('Person') // by name
customerType.extendsFrom(personInstance) // by ComplexType instance
extendsFrom(baseType: DataType | string | Type | object): boolean
Scope methods
inScope(scope?)
Returns true if this type is visible in the given scope (based on scopePattern). Types without a scopePattern are always in scope.
inScope(scope?: string | '*'): boolean
Field path utilities
parseFieldPath(fieldPath, options?)
Resolves a dot-separated field path against this type's field tree. Returns an array of ParsedFieldPath items — one per path segment — each containing the resolved field, dataType, and optional sign (+/-).
const segments = customerType.parseFieldPath('address.city');
// [{ fieldName: 'address', field: ..., dataType: AddressType }, { fieldName: 'city', field: ..., dataType: StringType }]
parseFieldPath(
fieldPath: string,
options?: { allowSigns?: 'first' | 'each'; scope?: string | '*' }
): ComplexType.ParsedFieldPath[]
normalizeFieldPath(fieldPath, options?)
Resolves a field path and returns the canonical dot-separated string (with optional sign prefix per segment).
normalizeFieldPath(
fieldPath: string,
options?: { allowSigns?: 'first' | 'each'; scope?: string }
): string
Codec generation
generateCodec(codec, options?)
Compiles a validation/transformation function for either encoding (output) or decoding (input) against this type's field schema. Used internally by adapters — call this when you need a validator outside the request lifecycle.
const decoder = customerType.generateCodec('decode', { scope: 'public' });
const result = decoder(rawInput);
const encoder = customerType.generateCodec('encode', { partial: true });
generateCodec(
codec: 'encode' | 'decode',
options?: DataType.GenerateCodecOptions
): Validator
Key codec options:
| Option | Type | Description |
|---|---|---|
scope | string | Only include fields visible in this scope. |
partial | boolean | 'deep' | All fields become optional. 'deep' applies recursively. |
projection | string[] | '*' | Field projection — include/exclude specific fields. |
ignoreReadonlyFields | boolean | Strip readonly fields (for input decoding). |
ignoreWriteonlyFields | boolean | Strip writeonly fields (for output encoding). |
keepKeyFields | boolean | Always include the key field regardless of other options. |
allowNullOptionals | boolean | Accept null in place of absent optional fields. |
Serialization
toJSON(options?)
Returns an OpraSchema.ComplexType plain object for schema export. Called automatically during document serialization.
toJSON(options?: ApiDocument.ExportOptions): OpraSchema.ComplexType
Obtaining a ComplexType instance
You do not construct ComplexType directly. Retrieve it from a document:
import { ComplexType } from '@opra/common';
const customerType = document.node.getDataType('Customer');
// or with type guard:
if (customerType instanceof ComplexType) {
for (const field of customerType.fields()) {
console.log(field.name);
}
}
→ ApiDocument · ApiField