@typesugar/core
v0.1.0
Published
π§ Core types and registry for typesugar macro system
Maintainers
Readme
@typesugar/core
Foundation types, registry, and context for the typesugar macro system.
Overview
@typesugar/core is the foundational package of the typesugar ecosystem. It defines the interfaces that all macros implement, the global registry where macros are registered, and the MacroContext that provides type checker access during macro expansion.
You need this package if you're writing custom macros. If you're just using typesugar macros, import from typesugar instead.
Installation
npm install @typesugar/core
# or
pnpm add @typesugar/coreRuntime Safety Primitives
In addition to macro infrastructure, @typesugar/core provides fundamental runtime safety utilities:
import { invariant, unreachable, debugOnly } from "@typesugar/core";
// Assert invariants (strippable in production)
function divide(a: number, b: number): number {
invariant(b !== 0, "Division by zero");
return a / b;
}
// Mark unreachable code paths (for exhaustiveness checking)
type Shape = { kind: "circle" } | { kind: "square" };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle": return Math.PI;
case "square": return 1;
default: unreachable(shape); // Type error if Shape is extended
}
}
// Debug-only code (stripped in production builds)
debugOnly(() => {
console.log("Internal state:", state);
validateDeepInvariants(state);
});Macro Types
typesugar supports six kinds of macros:
| Kind | Interface | Trigger | Example |
|------|-----------|---------|---------|
| Expression | ExpressionMacro | Function call | comptime(() => 1 + 1) |
| Attribute | AttributeMacro | Decorator | @operators class Vec { } |
| Derive | DeriveMacro | @derive(Name) | @derive(Eq, Clone) |
| Tagged Template | TaggedTemplateMacroDef | Tagged template | sql`SELECT * FROM users` |
| Type | TypeMacro | Type reference | type X = Add<1, 2> |
| Labeled Block | LabeledBlockMacro | Labeled statement | let: { x << expr } |
Defining a Custom Macro
Expression Macro
import { defineExpressionMacro, globalRegistry } from "@typesugar/core";
const myMacro = defineExpressionMacro({
name: "myMacro",
module: "@my-org/my-macros",
description: "Doubles a numeric literal at compile time",
expand(ctx, callExpr, args) {
const arg = args[0];
const type = ctx.typeChecker.getTypeAtLocation(arg);
if (type.isNumberLiteral()) {
return ctx.factory.createNumericLiteral(type.value * 2);
}
ctx.reportError(arg, "myMacro expects a numeric literal");
return callExpr;
},
});
globalRegistry.register(myMacro);Tagged Template Macro
import { defineTaggedTemplateMacro, globalRegistry } from "@typesugar/core";
const greetMacro = defineTaggedTemplateMacro({
name: "greet",
module: "@my-org/my-macros",
description: "Validates greeting templates at compile time",
expand(ctx, taggedTemplate, tag, template) {
// Validate template at compile time, emit optimized code
return ctx.factory.createStringLiteral("Hello, World!");
},
});
globalRegistry.register(greetMacro);MacroContext
The MacroContext is passed to every macro's expand() function. It provides:
interface MacroContext {
/** TypeScript's type checker β full type information access */
typeChecker: ts.TypeChecker;
/** AST node factory for creating new nodes */
factory: ts.NodeFactory;
/** The source file being transformed */
sourceFile: ts.SourceFile;
/** Report an error at a specific node */
reportError(node: ts.Node, message: string): void;
/** Report a warning */
reportWarning(node: ts.Node, message: string): void;
/** Generate a unique identifier name (hygienic) */
generateUniqueName(prefix: string): string;
/** Parse a string as a TypeScript expression */
parseExpression(code: string): ts.Expression;
}Registry
The globalRegistry is a singleton that holds all registered macros:
import { globalRegistry } from "@typesugar/core";
// Register a macro
globalRegistry.register(myMacro);
// Look up by name
const macro = globalRegistry.get("myMacro");
// Look up by module + name (import-scoped)
const macro = globalRegistry.getByModule("@my-org/my-macros", "myMacro");API Reference
Types
MacroKindβ"expression" | "attribute" | "derive" | "tagged-template" | "type" | "labeled-block"MacroDefinitionβ Union of all macro definition typesExpressionMacroβ Expression macro definitionAttributeMacroβ Attribute (decorator) macro definitionDeriveMacroβ Derive macro definitionTaggedTemplateMacroDefβ Tagged template macro definitionTypeMacroβ Type-level macro definitionLabeledBlockMacroβ Labeled block macro definitionDeriveTypeInfoβ Type information passed to derive macrosDeriveFieldInfoβ Field information withinDeriveTypeInfoComptimeValueβ Values representable at compile time
Functions
defineExpressionMacro(def)β Create an expression macro definitiondefineAttributeMacro(def)β Create an attribute macro definitiondefineDeriveMacro(def)β Create a derive macro definitiondefineTaggedTemplateMacro(def)β Create a tagged template macro definitiondefineTypeMacro(def)β Create a type macro definitiondefineLabeledBlockMacro(def)β Create a labeled block macro definition
Singletons
globalRegistryβ The globalMacroRegistryinstance
License
MIT
