Scalar Constant

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:
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
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'
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:
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
🎯Static vs Dynamic Defaults
Use static values for constants (0, "active"). Use factory functions for values that should be computed at creation time (dayjs(), new ObjectId()).
Custom Validation
The validate option accepts a function that returns true/false or throws an error. Use it for complex validation logic.

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:
IssueWrongCorrect
Enum caseenumOf('status', ['ACTIVE'])enumOf('status', ['active'])
Array syntaxfield(Array<Int>)field([Int])
Dynamic default{ default: dayjs() }{ default: () => dayjs() }
Missing exportclass Status extends enumOf(...)export class Status extends enumOf(...)
Optional fieldfield(ID, { nullable: true })field(ID).optional()
Important: For Date defaults that should be computed at creation time, always use a factory function: { default: () => dayjs() }

Implementation Checklist

  • File location: __scalar/<camelCase>/<camelCase>.constant.ts
  • Import via from '@akanjs/constant'
  • Import enumOf from '@akanjs/base' (if using enums)
  • Export all classes (scalar and enums)
  • Use PascalCase for class names
  • Use camelCase for enum values
  • Use [Type] syntax for arrays
  • Use factory functions for dynamic defaults
  • Use .optional() for nullable fields
  • Add 'as const' for large enum value arrays
💡 Pro Tips:
  • Keep scalars focused - if it grows too large, split it into multiple scalars
  • Scalars are value objects - avoid adding ID or timestamp fields (use Models for that)
  • Define enums before the scalar class that uses them
  • Don't forget to create dictionary.ts for i18n support
Released under the MIT License
Official Akan.js Consulting onAkansoft
Copyright © 2025 Akan.js. All rights reserved.
System managed bybassman