Tanu.js
Tanu.js is a JavaScript/TypeScript library designed to simplify the generation of TypeScript types and interfaces by providing a high-level, declarative abstraction over the complex TypeScript Compiler API. It specifically aims to mitigate the common practice of generating `.d.ts` files using error-prone, untyped template literal strings, promoting greater type safety and readability in generated code. Currently at version 0.2.0, the library is in an early, active development phase, implying potential for rapid evolution and API changes. Its key differentiator is a fluent API for defining TypeScript constructs like interfaces, enums, and types, including a sophisticated mechanism for handling self-referencing and cross-referencing types through lazy evaluation callback functions.
Common errors
-
ReferenceError: Cannot access 'MyType' before initialization
cause Attempting to define a self-referencing or mutually recursive type without utilizing the lazy evaluation callback function for `t.interface` or `t.type`.fixWrap the type definition object in an arrow function to allow for lazy resolution of the type reference: `const MyType = t.interface('MyType', () => ({ prop: MyType }));` -
Error: Module not found: Can't resolve 'tanu.js' in '...' OR Cannot find module 'tanu.js' from '...'
cause The `tanu.js` package has not been installed or is not correctly resolved by your module bundler/Node.js environment.fixEnsure the package is installed: `npm install tanu.js` or `yarn add tanu.js`. Check your `package.json` for correct installation.
Warnings
- gotcha As of version 0.2.0, Tanu.js is an early-stage library. Its API surface may undergo significant changes and breaking modifications in future minor or patch releases until it reaches a stable 1.0.0 version.
- gotcha When defining interfaces or types that are self-referencing or mutually recursive (e.g., a 'User' interface that contains an array of 'User' objects), it is crucial to use the callback pattern for `t.interface` or `t.type` to enable lazy evaluation. Failing to do so will result in runtime errors.
Install
-
npm install tanu -
yarn add tanu -
pnpm add tanu
Imports
- t
const t = require('tanu.js');import { t } from 'tanu.js'; - t.interface
import { interface } from 'tanu.js';import { t } from 'tanu.js'; const MyInterface = t.interface('MyInterface', { /* ... */ }); - t.generate
import { generate } from 'tanu.js';import { t } from 'tanu.js'; const result = await t.generate([/* ... */]);
Quickstart
import { t } from 'tanu.js';
const User = t.interface('User', {
id: t.number(),
email: t.string(),
name: t.optional({
first: t.string(),
last: t.string()
})
});
const MemberRole = t.enum('MemberRole', [
'DEFAULT',
'PRIVILEGED',
'ADMINISTRATOR'
]);
const Member = t.interface('Member', {
user: User,
role: MemberRole
});
const Organization = t.interface('Organization', {
name: t.comment(t.string(), [
'The organization name.',
'@see https://example.com/organization-name'
]),
description: t.optional(t.string()),
members: t.array(Member)
});
async function generateTypes() {
const result = await t.generate([User, MemberRole, Member, Organization]);
console.log(result);
}
generateTypes();