Library / SDK
typedgrammar/typed-japanese avatar
typedgrammar/typed-japanese

typed-japanese: Japanese grammar checked by the TypeScript compiler

🌸 Learn Japanese grammar with TypeScript

1,946 stars24 forksTypeScriptMIT

At a glance

What is it?
A type-level DSL that turns Japanese conjugation and sentence composition into TypeScript types, so the compiler rejects ungrammatical strings. It is built for programmers who already read TypeScript, not for general learners.
Who is it for?
Adopt typed-japanese if you write TypeScript daily and want Japanese conjugation rules expressed as types you can read and extend, or if you are prototyping a grammar-analysis interchange format for LLM output. Do not adopt it as a substitute for a Japanese course, a typing tutor, or a font or input-method tool; it does none of those.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 90 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem: Japanese correctness has no compiler

Conjugation in Japanese is regular enough to be taught as rules and irregular enough that learners get it wrong for years. A learner writing 買う (to buy) has to know that the te-form is 買って and the past is 買った, and that the same rule does not apply to 食べる, which becomes 食べて and 食べた. Textbooks present these as tables. Tables are not checkable.

Typed Japanese takes a different position: if the rules are deterministic, they can be encoded as TypeScript types, and if they are types, the compiler can verify them. The README states the project is a "TypeScript type-level library that enables the expression of complete Japanese sentences through the type system," creating a DSL based on Japanese grammar rules so that a subset of grammatically correct natural language can be written and verified by tsc.

The audience is narrow and specific. You need to be comfortable reading conditional types and template literal types to get anything out of this. The README's own framing is blunt about it: "If you can write TypeScript, you can understand Japanese!" That is the pitch, and it also names the barrier. Someone who wants to order coffee in Tokyo gets nothing here. Someone who wants to see 五段動詞 and 一段動詞 conjugation expressed as type transformations gets a working model.

How the type-level DSL represents verbs, adjectives and the copula

The mechanism is template literal types plus conditional types. A verb is not a string; it is an intersection describing its class and its parts. The README gives 買う as `GodanVerb & { stem: "買"; ending: "う" }` and 食べる as `IchidanVerb & { stem: "食べ"; ending: "る" }`. The stem and ending are separated so that `ConjugateVerb<T, Form>` can pattern-match on the ending and produce the right surface form for the requested form.

Verb classes follow the standard three-way split: Godan (五段動詞), Ichidan (一段動詞), and irregular, which the README limits to する and 来る. The supported forms are listed as Dictionary, Masu, Te, Ta, Nai, Potential, Passive, Causative, Volitional, Imperative, Conditional and Hypothetical. Adjectives split into I-Adjectives and Na-Adjectives, with four forms: Basic, Polite, Past and Negative. Irregularity is a flag on the type, visible in the README's `IAdjective & { stem: "い"; ending: "い"; irregular: true }` for いい.

The copula section is the most interesting design decision. The README argues the copula is "not a particle: like a verb or an adjective it inflects for politeness, tense and polarity," so it gets its own `ConjugateCopula<Taigen, Form>` mirroring the verb and adjective conjugators. It covers Plain, Polite, Past, PolitePast, Negative, PoliteNegative, NegativePast, PoliteNegativePast, CasualNegative, CasualPoliteNegative, Written and Te. The README also documents a deliberate omission: there is no generic attributive form, because な is licensed only for な-adjectives (静かな町) and never for plain nouns, which take の. That is a real grammatical boundary encoded as an absence in the API.

Above the word level, composition works through parts. `PhraseWithParticle` attaches a particle to a conjugated form, `ConnectedPhrases` joins two phrases with Japanese punctuation, and `JoinPhrasePartsValue` collapses an array of typed parts into one string. The README's longer example builds なんでそんなに慣れてんだよ from an adverb part, an intensifier part, a te-form verb, a contracted ん, a plain copula and a sentence-ending particle.

Installing typed-japanese and writing your first checked sentence

The package is published as `@typedgrammar/typed-japanese` at version 0.1.0, with `main` pointing at `dist/index.js` and `types` at `dist/index.d.ts`. The README does not include an install command, so the package name and entry points come from the repository's package.json. The project uses pnpm: the lockfile is `pnpm-lock.yaml`, and the playground instructions use pnpm.

A first real use is to define a verb and ask the compiler for a conjugated form. The README gives this pattern directly:

typescript
type 買う = GodanVerb & { stem: "買"; ending: "う" };
type 買うTe = ConjugateVerb<買う, "Te">; // 買って
type 買うTa = ConjugateVerb<買う, "Ta">; // 買った

What you should see is that `買うTe` resolves to the literal 買って and `買うTa` to 買った. If your editor shows the alias instead of the resolved string, hovering the type in a modern TypeScript version expands it.

The verification step is the point of the library. Assign a string literal to the type, and the compiler accepts only the matching surface form:

typescript
const properExample: ヒンメルならそうした = "ヒンメルならそうした";
// "If it were Himmel, he would do so"

That example comes from the README and composes a proper noun, an irregular する verb, a demonstrative action in past form, and a conditional phrase with なら. Change one character and the assignment fails, which is the entire value proposition: the type checker becomes the grammar checker.

If you want to explore before installing anything, the README points at an interactive playground at typedgrammar.github.io/typed-japanese, described as an in-browser TypeScript editor where the compiler resolves conjugations live, alongside a Verb Lab, Adjective Lab, Phrase Builder and Sentence Gallery. The playground can also be run locally:

bash
cd playground && pnpm install && pnpm dev

The repository's own checks are run with `pnpm typecheck` (which is `tsc --noEmit`), `pnpm build` (`tsc`), `pnpm lint` (eslint over .ts and .tsx), and `pnpm test`, which the package.json defines as `pnpm typecheck && pnpm lint`. Note what that means: there is no separate runtime test suite. The type definitions are the test.

Where the type-level approach breaks down

The first limitation is coverage. The README describes the library as covering "a subset of grammatically correct natural language," and that subset is enforced by what the source actually defines. The README lists which conjugation forms and particles exist, but it does not enumerate every particle, every sentence pattern, or every lexical class. If a construction is not modeled in `src/`, you cannot express it, and the compiler will not tell you the grammar is fine; it will tell you the type does not exist. That is a different failure mode from being wrong.

The second limitation is the cost of type-level computation. Every conjugation is a type transformation evaluated by the compiler. The README's technical section names template literal types, conditional types and mapped types as the machinery. Those are the expensive parts of the type system. The repository does not publish compile-time measurements, and nothing in the README describes performance characteristics, so there is no basis for a claim either way. What can be said is that this style of library concentrates work in the checker, and the project's own `test` script is a typecheck, so the typecheck is the build.

The third issue is that the library verifies form, not meaning. いいよ, 来いよ and the assembled なんでそんなに慣れてんだよ are checked as strings against types. Nothing in the README suggests the system models speaker intent, register beyond what the conjugation forms encode, or whether a sentence is appropriate in context. A grammatically well-formed sentence that is rude or nonsensical still typechecks.

Finally, the README's motivation for an LLM interchange format is explicitly speculative. It says the project "explores" the idea that LLMs could return grammar analysis in this format instead of JSON, "enabling verification through TypeScript's type checker to improve correctness." That is a proposal, not a shipped integration. Treat it as a direction, not a feature.

typed-japanese compared with a runtime grammar library

The obvious alternative class is a runtime Japanese morphological analyzer or grammar library, which tokenizes and analyzes text at execution time. The difference in approach is where the checking happens and what it can see.

A runtime analyzer takes a finished string and tells you what it is: parts of speech, dictionary forms, readings. It works on arbitrary input, including text a user typed, text scraped from a page, or text an LLM produced. It also ships as executable code and runs in production.

Typed Japanese inverts this. It does not analyze strings; it constructs them from typed parts and rejects mismatches at compile time. That means it can only check sentences you wrote in the DSL. It cannot validate a string that arrived at runtime, because by then the compiler is gone. If your goal is to inspect user input or model output, a runtime analyzer is the right tool and this library is the wrong one.

The trade is real in both directions. Typed Japanese gives you an exhaustive, machine-checkable statement of the conjugation rules for the forms it covers, and it gives you that at zero runtime cost, since the work happens during compilation. A runtime analyzer gives you breadth over real text at the cost of doing the work every time it runs. The README's own framing of the LLM use case is an attempt to bridge the two, by having the model emit typed structures rather than free text so the checker can still participate. Whether that works in practice is not something the README demonstrates.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-06-21. The version in package.json is 0.1.0, and no releases were retrieved, so there is no published changelog to read before upgrading. That matters more than usual here: because consumers depend on exported type names and on the exact shapes of `GodanVerb`, `IchidanVerb`, `IAdjective`, `NaAdjective`, `IrregularVerb`, `ConjugateVerb`, `ConjugateAdjective`, `ConjugateCopula`, `PhraseWithParticle`, `ConnectedPhrases` and `JoinPhrasePartsValue`, a rename or a change to a form union is a breaking change for every file that uses the DSL, even if no runtime behaviour changes.

The dependency surface is small and entirely dev-side. package.json lists eslint 9, the TypeScript ESLint plugin and parser at 8.61, and typescript 5.9.3 as devDependencies, with no runtime dependencies at all. That is a favourable shape for a library of this kind: there is nothing to audit at runtime, and upgrading means tracking TypeScript itself, which is the actual constraint. The type-level techniques the library relies on are sensitive to compiler behaviour, so the TypeScript version in your project is part of your compatibility story.

Licensing is MIT, per both the LICENSE file and the `license` field in package.json. MIT permits use, modification and redistribution with the licence and copyright notice retained. That is a permissive arrangement with few obligations, but it is not legal advice, and if you are embedding the types in a commercial product you should have your own counsel confirm the notice requirements rather than relying on this summary.

Editorial conclusion

Adopt typed-japanese if you write TypeScript daily and want Japanese conjugation rules expressed as types you can read and extend, or if you are prototyping a grammar-analysis interchange format for LLM output. Do not adopt it as a substitute for a Japanese course, a typing tutor, or a font or input-method tool; it does none of those. Before committing, run pnpm typecheck in a clone to confirm the toolchain matches, read src/ to see which particles and sentence patterns actually exist, and check whether the copula and adjective systems cover the forms you need. The library is at version 0.1.0 and its test script is pnpm typecheck && pnpm lint, so treat the type definitions themselves as the specification you are buying into.

Frequently asked questions

What is typed-japanese?

It is a TypeScript type-level library that expresses Japanese sentences through the type system, creating a DSL based on Japanese grammar rules so a subset of grammatically correct language can be written and verified by the compiler. It is published as @typedgrammar/typed-japanese and licensed MIT.

How do I install and run typed-japanese?

The README does not give an install command, but package.json names the package @typedgrammar/typed-japanese at version 0.1.0, with types at dist/index.d.ts. The playground is run with cd playground && pnpm install && pnpm dev, and the repository's own checks are pnpm typecheck and pnpm test.

Does typed-japanese help me type Japanese on a keyboard or phone?

No. The project is a TypeScript library for representing and checking Japanese grammar as types. It does not provide an input method, a keyboard, a font, or a typing practice tool; the README describes a type-level DSL and an in-browser TypeScript playground.

How do I add a particle to a conjugated verb in typed-japanese?

The README shows PhraseWithParticle wrapping a conjugated form, for example PhraseWithParticle<ConjugateVerb<来る, "Imperative">, "よ"> for 来いよ. Two such phrases are then joined with ConnectedPhrases.

Official sources

  1. Issues
  2. License: MIT
  3. Project website
  4. README
  5. typedgrammar/typed-japanese on GitHub
Community notes

Community notes