Skip to content

Core Type System

chant provides a lexicon-agnostic declarative specification system. This guide covers the core types you’ll use when building with chant.

A Declarable is any entity that can be declared in a specification. All declarables share a common marker and an entityType property for runtime identification.

import { isDeclarable } from "@intentius/chant";
if (isDeclarable(value)) {
console.log(value.entityType);
}

Parameters that can be passed to declarable entities extend CoreParameter:

interface CoreParameter extends Declarable {
readonly parameterType: string;
}

Outputs from declarable entities extend CoreOutput:

interface CoreOutput extends Declarable {
readonly value: unknown;
}

An Intrinsic represents a lexicon-provided function that will be resolved at build time. Intrinsics are placeholders for values that depend on other resources or runtime information.

import { isIntrinsic } from "@intentius/chant";
if (isIntrinsic(value)) {
const serialized = value.toJSON();
}

AttrRef is a built-in intrinsic for referencing attributes of other entities. It uses deferred resolution — the logical name is assigned during discovery, not construction.

import { AttrRef } from "@intentius/chant";
const arnRef = new AttrRef(bucket, "arn");
arnRef.toJSON();
// Produces the lexicon's reference format

The Value<T> type represents a property that can either be a concrete value or an intrinsic:

import type { Value } from "@intentius/chant";
interface MyConfig {
endpoint: Value<string>;
port: Value<number>;
}

This allows specifications to reference values that aren’t known until build time.

Thrown during file discovery and module loading:

// Types: "import" | "resolution" | "circular"
import { DiscoveryError } from "@intentius/chant";
throw new DiscoveryError("config.ts", "Module not found", "import");

Thrown during the build/serialization phase:

import { BuildError } from "@intentius/chant";
throw new BuildError("MyResource", "Invalid configuration");

Represents a lint rule violation with location information:

import { LintError } from "@intentius/chant";
const error = new LintError(
"config.ts", 10, 5, "no-unused",
"Variable is declared but never used"
);
const mySerializer: Serializer = {
name: "my-lexicon",
rulePrefix: "MD",
serialize(entities: Map<string, Declarable>): string {
return JSON.stringify({ entities: Array.from(entities.keys()) });
}
};
const myRule: LintRule = {
id: "my-rule",
severity: "error",
category: "correctness",
check(context: LintContext): LintDiagnostic[] {
return [];
},
};

Severity levels: "error" | "warning" | "info"

Categories: "correctness" | "style" | "performance" | "security"