The constant file (*.constant.ts) is where you define the schema for your scalar. Using the via() function and enumOf() helper, you create type-safe, reusable value objects that can be embedded in other models.
File Structure and Location
Scalar constants follow strict naming conventions and directory structure:
field
Description
Example
Directory
camelCase
File
<scalarName>.constant.ts
Scalar Class
PascalCase
Enum Class
PascalCase
Enum Values
camelCase
Directory
camelCase
File
<scalarName>.constant.ts
Scalar Class
PascalCase
Enum Class
PascalCase
Enum Values
camelCase
Basic Syntax with via()
The via() function is the foundation for defining scalars. It takes a callback that receives the field() function, which you use to define each field's type and options.
Basic Structure
Here's a simple real-world example:
restrictInfo.constant.ts
method
Description
via((field) => ({...}))
Creates a class with typed fields. The callback receives the field() helper function.
field(Type)
Defines a single field. First argument is the type (String, Number, Date, etc.).
field(Type, { options })
Optional second argument is an options object for defaults, validation, etc.
via((field) => ({...}))
Creates a class with typed fields. The callback receives the field() helper function.
field(Type)
Defines a single field. First argument is the type (String, Number, Date, etc.).
field(Type, { options })
Optional second argument is an options object for defaults, validation, etc.
Available Field Types
Akan.js provides several built-in types that you can use with the field() function:
Primitive Types
Array types are defined by wrapping the type in square brackets:
Array Types
Optional fields can be defined using the .optional() chain:
fileMeta.constant.ts
Defining Enums with enumOf()
The enumOf() function creates typed enum classes. Define enums before using them in your scalar fields.
Basic Enum
For more complex enums with many values, use "as const" for better type inference:
Multiple enums with 'as const'
field
Description
enumOf(name, values)
First argument is the enum name (used in dictionary/GraphQL). Second is the value array.
camelCase Values
Always use camelCase for enum values (e.g., "waitPay", not "WAIT_PAY").
as const
Add 'as const' to the values array for better TypeScript type inference.
enumOf(name, values)
First argument is the enum name (used in dictionary/GraphQL). Second is the value array.
camelCase Values
Always use camelCase for enum values (e.g., "waitPay", not "WAIT_PAY").
as const
Add 'as const' to the values array for better TypeScript type inference.
Field Options
The second argument to field() is an options object that configures defaults, validation, and behavior:
Option
Type
Default
Description
Example
default
Any | Function
undefined
Default field value (static or factory function)
min
Number
-
Minimum numeric value
max
Number
-
Maximum numeric value
minlength
Number
-
Minimum string length
maxlength
Number
-
Maximum string length
validate
Function
-
Custom validation function
example
Any
-
Example value for documentation
default:Any | Function:undefined
Default field value (static or factory function)
min:Number:-
Minimum numeric value
max:Number:-
Maximum numeric value
minlength:Number:-
Minimum string length
maxlength:Number:-
Maximum string length
validate:Function:-
Custom validation function
example:Any:-
Example value for documentation
Here's how to use various options:
Options Examples
Adding Instance Methods
You can add instance methods directly to the scalar class for computed properties and utility functions:
Instance Methods
💡
Instance methods have access to all fields via 'this'. Use them for calculations based on field values.
🔧
Methods defined in constant.ts are available on both server and client. For server-only logic, use document.ts instead.
Common Mistakes
Avoid these common mistakes when defining scalar constants:
Issue
Wrong
Correct
Enum case
enumOf('status', ['ACTIVE'])
enumOf('status', ['active'])
Array syntax
field(Array<Int>)
field([Int])
Dynamic default
{ default: dayjs() }
{ default: () => dayjs() }
Missing export
class Status extends enumOf(...)
export class Status extends enumOf(...)
Optional field
field(ID, { nullable: true })
field(ID).optional()
Important: For Date defaults that should be computed at creation time, always use a factory function: { default: () => dayjs() }