Typed Japanese: a sentence is a type, and an adjective only gets four conjugation forms
🌸 Learn Japanese grammar with TypeScript
At a glance
- What is it?
- A type-level library that expresses Japanese sentences in the type system, where verbs carry twelve named forms, adjectives carry four, and the copula is modelled as a conjugable word rather than a particle because attributive na is licensed for na-adjectives and never for plain nouns.
- Who is it for?
- Typed Japanese is two projects wearing one name. There is a teaching playground that resolves conjugations in the browser and is genuinely good for learning verb forms.
- 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 113 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 October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Twelve verb forms, four adjective forms, and twelve copula forms
The verb system supports twelve named forms: dictionary, polite, te, past, negative, potential, passive, causative, volitional, imperative, conditional, and hypothetical. That is a thorough grid, and it covers the conjugations that are actually hard in Japanese rather than just tense and politeness.
The adjective system supports four: basic, polite, past and negative. So an i-adjective has no potential form, no causative form and no imperative form, which is correct linguistically and a good illustration of how a type system refuses forms that do not exist.
The copula is where the depth is, and the reasoning is spelled out in the readme rather than assumed. The copula is treated as a conjugable word rather than a particle, modelled by a function that mirrors the verb and adjective ones, with twelve forms of its own: plain and polite, past and polite past, four negative variants including casual ones, a written form, and a connective form.
The most interesting design note is a negative one. The copula has no generic attributive form, because the na that joins a modifier to a noun is licensed for na-adjectives and never for plain nouns, and a counterexample is given. So the attributive lives in the adjective system where it belongs, rather than in the copula where a learner would expect it.
Verb classes are three types, and the conjugational data is in the type
Japanese verbs split into three classes and the library mirrors the textbook split exactly.
Godan verbs, called group one or u-verbs, are identified by their final character, and nine are enumerated. Ichidan verbs, called group two or ru-verbs, always end in one character. Irregular verbs are exactly two, and both are listed.
The encoding is where it gets interesting, because a verb is not an opaque parameter. It is an intersection of a class marker with its own conjugational data as string literal fields:
type 買う = GodanVerb & { stem: "買"; ending: "う" };
type 買うTe = ConjugateVerb<買う, "Te">; // 買って
type 買うTa = ConjugateVerb<買う, "Ta">; // 買った
type 食べる = IchidanVerb & { stem: "食べ"; ending: "る" };
type 食べるTe = ConjugateVerb<食べる, "Te">; // 食べて
type 食べるTa = ConjugateVerb<食べる, "Ta">; // 食べたSo the stem and the ending are the data, and the conjugation function computes a string literal type as its result. A class marker plus the ending is enough to derive both the te form and the past form, which is exactly the rule a textbook would state in prose and exactly the rule a conditional type can encode.
One adjective is flagged as irregular in the same way, which tells you the mechanism is meant for exceptions rather than being a toy that only handles regular shapes.
A sentence is a type, so a wrong sentence is a compile error
The verification story is the compiler itself. A sentence becomes a type name built from its parts, and assigning a string to that type only type-checks when the string matches the type exactly.
The header example builds one. A proper noun becomes a type. An irregular verb becomes a type. A demonstrative action is constructed by combining the demonstrative, the verb and the past form. A conditional phrase combines the noun with the conditional particle and the consequent. Then the example assigns the finished Japanese string to that type, and the assignment is the test.
Everything above it is composition. Phrases take particles. Phrases connect to phrases. Sentences take a tuple of parts, and the parts are typed by role: an adverb part, an intensifier part, a verb part with a chosen form, a contracted nominalizer part, a copula part, and a sentence-ending particle. A join function flattens the tuple into one string, and the example asserts a full colloquial sentence with its translation as a comment.
That last part is the pedagogical payoff. A learner is not asked to remember that a question adverb plus an intensifier plus a te-form verb plus a contraction plus a copula plus a particle produces one particular sentence. They are asked to assemble the parts, and the compiler tells them whether the assembly is grammatical.
The AI claim is a typed format a model could emit instead of JSON
The second project inside this repository is a proposal, and it is the more speculative of the two.
The argument goes: a language model asked to analyse a Japanese sentence could return its analysis in this type format instead of returning JSON. Because the format is typed, the model's output would be checked by the type system on arrival. Grammatical mistakes would become compile errors rather than plausible-looking JSON that has to be validated by hand.
It is a good idea, and the same mechanism that catches a learner's wrong te-form would catch a model's wrong particle attachment. Nothing in the readme suggests any model currently emits it, and the package has no releases, so this is a research direction rather than a capability.
The limitation follows from the design rather than from the documentation. A format a model must emit correctly is only as good as the distinctions it can express, and the library's own shape shows where those are: deep on verbs, shallow on adjectives, and explicit about one particular licensing rule. A model reasoning about a Japanese sentence needs considerably more than that to be worth verifying, which is why the interesting part of this project is likely to be the failures rather than the successes.
The playground compiles conjugations live, with four labs
The interactive part is a browser-based TypeScript editor where the compiler resolves conjugations as you type, and around it sit four purpose-built labs: one for verbs, one for adjectives, a phrase builder, and a sentence gallery.
The distinction between the editor and the labs is the right one. The editor is where you write a type and watch the checker agree or disagree, which teaches the encoding. The labs are where you do the ordinary textbook exercise, which teaches the grammar. Neither is a substitute for the other, and a playground that only offered the editor would teach the clever part and leave the grammar untouched.
The source lives in its own directory in the repository, with its own install and development command, and there is a StackBlitz link for trying it without a local checkout. Running it locally is a directory change, an install with the same package manager the repository uses, and a development command.
Alongside it there is a long blog post in the repository root that the readme points to, which sets out how the type system can be used to learn Japanese grammar from first principles. Its stated method is to start from basic programming concepts and build up to conditional sentences and interrogative phrases, which is a slower path than a grammar book and a much more durable one.
A macOS translation app sits in the tree and the readme never mentions it
The repository has an applications directory, and the manifest carries two scripts pointing into it. Both run a file in a folder named for a translation tool, and both are invoked with a different JavaScript runtime from the one the repository otherwise uses.
There is a run script for the application and a smoke-test script beside it, and the smoke test takes a flag that suppresses launching the app. That shape, a separate smoke test with a no-launch switch, suggests the author can verify the app starts up correctly without a window appearing, which is exactly the problem you hit when a desktop wrapper needs a display it does not have.
Two things are worth noting. The runtime those scripts need is not among the declared dependencies, and the repository's lock file belongs to a different package manager. So those two scripts cannot be run from a plain install of the repository as declared. And nothing in the visible readme describes the application, its purpose or its relationship to the type library, which means it is either work in progress or a separate tool sharing a repository.
For anyone evaluating the library, the practical consequence is small: the published artefact is the type library, and the application is extra weight in the repository rather than part of what you install.
Version 0.1.0, no releases, no author, and a test that is the type checker
The manifest is small and has three things missing that you would expect to be there.
The version is 0.1.0 and the repository has no releases, so there is nothing to pin and nothing to compare against. The author field is present and empty. And the entry points point at a build output directory, meaning the package ships compiled JavaScript and its declaration files, produced by running the compiler directly, with the type-only code doing its work at compile time rather than at run time.
The script table has one entry worth calling out. The test script is a chain of the type checker and the linter, and that is all. There is no unit test framework, no assertion library, and no test directory in the tree. For a library whose entire output is types, that is more defensible than it sounds: the checker compiles every example, and the examples in the readme are the specification. But it also means nothing verifies that a conjugation produces the right string beyond the compiler agreeing with itself, unless someone is reading the comments.
One small leftover: the lint script still passes an extension flag, which belongs to an older configuration style, while the repository has a flat configuration file. Whether that combination works depends on the linter version, and it is the kind of thing that breaks on a major upgrade rather than on a day-to-day run.
The licence is MIT, the default branch is the conventional one, the repository is not archived, and the last push is dated 21 June 2026.
Editorial conclusion
Typed Japanese is two projects wearing one name. There is a teaching playground that resolves conjugations in the browser and is genuinely good for learning verb forms. Underneath it is a type-level encoding of Japanese grammar that a compiler will check, and that encoding is the interesting part because it forces decisions about which distinctions matter and which do not.
What to check before you build on it. The adjective system is shallow next to the verb system, which means the library is strong exactly where Japanese is hard and thin where it is easy. The copula carries its own twelve forms, including casual and written variants, so the deepest modelling is not on the verb. The package is at version 0.1.0 with no published releases, and the manifest has no author field, so pin a commit rather than a version. The stated vision, a typed format a language model can emit instead of JSON so the type checker can verify it, is a proposal rather than a feature.
And expect the two language conventions that will trip you up as a learner to be encoded as errors rather than explained: the attributive form of na, which is licensed for na-adjectives and forbidden for plain nouns, is the clearest example in the whole codebase.
Frequently asked questions
How does Typed Japanese verify a Japanese sentence?
A sentence is expressed as a type built from typed parts, and assigning a string to that type only type-checks when the string matches. A grammatical mistake becomes a compile error rather than a wrong answer you have to notice.
Which conjugation forms does Typed Japanese support for verbs?
Twelve: dictionary, polite, te, past, negative, potential, passive, causative, volitional, imperative, conditional and hypothetical. Adjectives get four of those: basic, polite, past and negative.
Why is the Japanese copula modelled as a word rather than a particle?
Because it inflects for politeness, tense and polarity like a verb or an adjective, so it gets its own conjugating function with twelve forms. Its attributive form is deliberately absent, since na is licensed only for na-adjectives and never for plain nouns.
Does Typed Japanese have automated tests?
Not in the usual sense. The test script runs the type checker and the linter, and there is no test framework or test directory in the repository. Verification comes from the compiler accepting or rejecting the examples.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/typedgrammar-typed-japanese)