# tanu

> Generate TypeScript types and interfaces using JavaScript or TypeScript code

Latest version **0.2.0** (published 2024-06-15) · MIT license · 0 weekly downloads

## Install

```sh
npm install tanu
pnpm add tanu
yarn add tanu
bun add tanu
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.2.0 |
| Published | 2024-06-15 |
| First published | 2022-08-07 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 2 |
| Unpacked size | 46.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Aries Clark |
| Maintainers | ariesclark |
| Keywords | typescript, compiler api, abstraction, wrapper, tsc, generation |

## Links

- npm: https://www.npmjs.com/package/tanu
- npm.io page: https://npm.io/package/tanu

## Dependencies (2)

- [tslib](https://npm.io/package/tslib.md) ^2.6.3
- [typescript](https://npm.io/package/typescript.md) ^5.4.5

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 0.2.0 (latest) — 2024-06-15
- 0.1.13 — 2022-08-16
- 0.1.12 — 2022-08-16
- 0.1.11 — 2022-08-16
- 0.1.10 — 2022-08-16
- 0.1.9 — 2022-08-15
- 0.1.8 — 2022-08-15
- 0.1.7 — 2022-08-15
- 0.1.6 — 2022-08-11
- 0.1.5 — 2022-08-09
- 0.1.4 — 2022-08-08
- 0.1.3 — 2022-08-08
- 0.1.2 — 2022-08-08
- 0.1.1 — 2022-08-08
- 0.1.0 — 2022-08-07

## README

# Tanu 🦝

A simplified abstraction of the TypeScript Compiler API for defining and generating source files.

[![npm](https://img.shields.io/npm/v/tanu)](https://npm.im/tanu) [![GitHub issues](https://img.shields.io/github/issues/ariesclark/tanu.js) ![GitHub Repo stars](https://img.shields.io/github/stars/ariesclark/tanu.js?style=social)](https://github.com/ariesclark/tanu.js)

- [Tanu 🦝](#tanu-)
  - [Why?](#why)
  - [What does Tanu mean? 🦝](#what-does-tanu-mean-)
  - [How do I use this?](#how-do-i-use-this)

### Why?

I've always hated the fact that the majority of packages generate TypeScript files from a [ridiculously long template literal string](https://github.com/prisma/prisma/blob/44e1a8d16d62db62fbe8cc9c3e7ed0801617227a/packages/client/src/generation/TSClient/PrismaClient.ts), It's not type safe or even readable at all, and I saw a cool tweet.

<a href="https://twitter.com/mattpocockuk/status/1554766319165358081"><img src="https://i.imgur.com/5oDLeJn.png" width="50%"/></a>

Yes Matt, It does exist now.

### What does Tanu mean? 🦝

[Tanuki (a cute animal)](https://en.wikipedia.org/wiki/Japanese_raccoon_dog) but I removed the last two characters cause `tanuki` was already taken on npm, and sounded cool enough for me. _Naming things is hard, okay?_

### How do I use this?

```ts
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),
});

const result = await t.generate([User, MemberRole, Member, Organization]);
console.log(result);
```

```ts
// the generated result.

export interface User {
  id: number;
  email: string;
  name?:
    | {
        first: string;
        last: string;
      }
    | undefined;
}
export enum MemberRole {
  DEFAULT,
  PRIVILEGED,
  ADMINISTRATOR,
}
export interface Member {
  user: User;
  role: MemberRole;
}
export interface Organization {
  /**
   * The organization name.
   * @see https://example.com/organization-name
   */
  name: string;
  description?: string | undefined;
  members: Array<Member>;
}
```

### What about interfaces that reference themselves, or cross-reference each other?

Passing in a callback to the `t.interface` method will lazily populate the interface with its returned values. This will ensure that you can self-reference or cross-reference the interface, and it will be available by generation.

```ts
import { t } from "tanu.js";

const User = t.interface("User", () => ({
  users: t.array(User),
  posts: t.array(Post),
  authoredComments: t.array(Comment),
}));

const Post = t.interface("Post", () => ({
  author: User,
  text: t.string(),
  images: t.array(t.string()),
  postComments: t.array(Comment),
}));

const Comment = t.interface("Comment", {
  author: User,
  post: Post,
  text: t.string(),
});

const CommentReply = t.type("CommentReply", () => ({
  parent: CommentReply,
  author: User,
  post: Post,
  text: t.string(),
}));

const result = await t.generate([User, Post, Comment, CommentReply]);
console.log(result);
```

```ts
// the generated result

export interface User {
  users: Array<User>;
  posts: Array<Post>;
  authoredComments: Array<Comment>;
}
export interface Post {
  author: User;
  text: string;
  images: Array<string>;
  postComments: Array<Comment>;
}
export interface Comment {
  author: User;
  post: Post;
  text: string;
}
export type CommentReply = {
  parent: CommentReply;
  author: User;
  post: Post;
  text: string;
};
```

---
_Source: https://npm.io/package/tanu · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
