Skip to content

Supported TypeScript Types ​

TRAPI resolves TypeScript types through the compiler's own type checker, so the supported set tracks what the compiler itself understands. This page catalogues what is modelled, with notes on how each maps to OpenAPI output.

Primitives ​

TypeScriptMetadata typeNameOpenAPI
stringstringtype: string
number (default)doubletype: number, format: double
booleanbooleantype: boolean
bigintbiginttype: integer
voidvoidOmitted response content
undefinedundefinedNullable marker
null—Nullable marker
neverneverNo schema emitted
anyanyNo schema constraint

Numeric Refinements ​

A plain number resolves to DoubleType (OpenAPI type: number, format: double). To emit a more specific shape, either use a decorator from the IS_* family or a JSDoc tag on the containing declaration:

DecoratorJSDoc tagMetadata typeNameOpenAPI typeOpenAPI format
@IsInt()@isIntintegerintegerint32
@IsLong()@isLonglongintegerint64
@IsFloat()@isFloatfloatnumberfloat
@IsDouble()@isDoubledoublenumberdouble

TypeScript's bigint is a separate type and resolves to BigintType (type: integer, no format).

Date & Binary ​

TypeScriptMetadataOpenAPI
DateDateTimeTypetype: string, format: date-time
custom date-only typeDateTypetype: string, format: date
BufferBufferTypetype: string, format: binary
custom byte / binary typesByteType / BinaryTypetype: string, format: byte / binary

Object Types ​

Interfaces and Classes ​

Property enumeration walks inheritance, including classes declared in sibling files:

typescript
class Base {
    id: string;
}

class User extends Base {
    name: string;
}
// -> User has { id: string, name: string }

Index Signatures ​

Modelled as additionalProperties on the emitted schema.

typescript
type Dictionary = { [key: string]: string };
// OpenAPI: { type: 'object', additionalProperties: { type: 'string' } }

Optional Properties ​

typescript
type User = { name: string; email?: string };
// required: ['name']

Composite Types ​

Unions ​

typescript
type Status = 'active' | 'inactive' | 'banned';
// OpenAPI v3: { type: 'string', enum: ['active', 'inactive', 'banned'] }

Mixed unions (e.g. string | number) emit an oneOf schema.

Intersections ​

typescript
type Admin = User & { permissions: string[] };
  • V2 emitter: properties are flattened into a single object schema.
  • V3 emitter: emitted as allOf composing each member.

Tuples ​

typescript
type Pair = [name: string, value: number];

The metadata models this as a TupleType with named elements. OpenAPI has no direct tuple primitive, so the emitter degrades to array with anyOf items. Consumers that need the faithful tuple representation can read it from the metadata directly.

Utility Types ​

Handled explicitly by TRAPI's resolver:

  • Partial<T> — all properties optional
  • Required<T> — all properties required
  • Readonly<T> — modifier only; structurally identical
  • Pick<T, K> — subset of properties
  • Omit<T, K> — excludes properties
  • Record<K, V> — keyed map
  • NonNullable<T> — strips null | undefined

Delegated to the TypeScript type checker (TRAPI lets the compiler compute the resolved type, then walks the result):

  • Extract<T, U>
  • Exclude<T, U>
  • ReturnType<T>
  • Parameters<T>
  • Awaited<T>
  • InstanceType<T>
  • ConstructorParameters<T>

Other utility types may still resolve correctly via the compiler fallback, but are not guaranteed.

Generics ​

Generic type parameters are substituted before the metadata is emitted. A generic controller method with a concrete return type is fully resolved:

typescript
async findOne(@Path('id') id: string): Promise<User> {}
// resolves the `Promise<User>` wrapper; return type is `User`

Generic base classes with unresolvable type parameters are skipped gracefully — the concrete subclass still contributes its own methods.

Enums ​

Both string and numeric enums:

typescript
enum Role { Admin = 'admin', User = 'user' }
// OpenAPI v3: { type: 'string', enum: ['admin', 'user'] }

enum Priority { Low, Medium, High }
// OpenAPI v3: { type: 'integer', enum: [0, 1, 2] }

Use x-enum-varnames (in data.extra) if you need the variant names surfaced for code generators.

Nullable Types ​

T | null is modelled as a nullable T:

  • V2 emitter: x-nullable: true (non-standard)
  • V3 emitter: nullable: true

$ref siblings are handled correctly: V3 wraps the $ref in an allOf when nullable is set, so the output stays spec-compliant.

Circular References ​

Self-referential types work. They emit $ref pointers to the named schema.

typescript
type TreeNode = { value: string; children: TreeNode[] };

Not Supported ​

  • Template literal types — emitted as plain string
  • Conditional types where the condition cannot be evaluated statically
  • Arbitrary mapped types with key remapping — simple mapped types work through the explicit utility set above

For gaps that matter to you, open an issue — the metadata layer is deliberately extensible.