Skip to content

Commit 5fd1c0b

Browse files
Yifeng "Evan" Wangclaude
andcommitted
feat: scaffold Typed Korean — Dancheong theme, Korean grammar type-DSL, build/deploy pipeline
Fork of typed-japanese adapted for Korean: - src/: Korean grammar type-DSL (verbs/adjectives with morphological bases, 이다 copula, particles, space-aware Sentence composition) - playground/: Dancheong (단청/obangsaek) theme; Korean fonts; analyzer + vocab reworked for Hangul; bilingual zh/en UI teaching Korean - CI + GitHub Pages deploy at base /typed-korean/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 parents  commit 5fd1c0b

96 files changed

Lines changed: 12867 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
verify:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
16+
- name: Install pnpm
17+
uses: pnpm/action-setup@v4
18+
with:
19+
version: 9
20+
21+
- name: Set up Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '22'
25+
cache: 'pnpm'
26+
27+
- name: Install dependencies
28+
run: pnpm install
29+
30+
- name: Run test
31+
run: pnpm run test
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Deploy Playground
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
# Allow one concurrent deployment, cancelling in-progress runs.
14+
concurrency:
15+
group: pages
16+
cancel-in-progress: true
17+
18+
jobs:
19+
build:
20+
runs-on: ubuntu-latest
21+
defaults:
22+
run:
23+
working-directory: playground
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Install pnpm
28+
uses: pnpm/action-setup@v4
29+
with:
30+
version: 9
31+
32+
- name: Set up Node.js
33+
uses: actions/setup-node@v4
34+
with:
35+
node-version: "22"
36+
cache: pnpm
37+
cache-dependency-path: playground/pnpm-lock.yaml
38+
39+
- name: Install dependencies
40+
run: pnpm install
41+
42+
- name: Build
43+
run: pnpm build
44+
45+
- name: Upload artifact
46+
uses: actions/upload-pages-artifact@v3
47+
with:
48+
path: playground/dist
49+
50+
deploy:
51+
needs: build
52+
runs-on: ubuntu-latest
53+
environment:
54+
name: github-pages
55+
url: ${{ steps.deployment.outputs.page_url }}
56+
steps:
57+
- name: Deploy to GitHub Pages
58+
id: deployment
59+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
node_modules
3+
dist
4+
dist-server
5+
*.tsbuildinfo

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2025-present, Yifeng Wang
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
# Typed Korean
2+
3+
**If you can write TypeScript, you can understand Korean!**
4+
5+
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/typedgrammar/typed-korean)
6+
7+
![demo](./images/demo.png)
8+
9+
> **New: [Interactive Playground →](https://typedgrammar.github.io/typed-korean/)** — an in-browser TypeScript editor where the compiler resolves conjugations live, plus a Verb Lab, Adjective Lab, Phrase Builder, and Sentence Gallery. ([source](./playground) · run locally with `cd playground && pnpm install && pnpm dev`)
10+
11+
Typed Korean is a TypeScript type-level library that enables the expression of complete Korean sentences through the type system. It creates a domain-specific language (DSL) based on Korean grammar rules, allowing a subset of grammatically correct natural language to be written and verified using TypeScript's compiler.
12+
13+
This project also explores an intermediate format for AI in language learning. For example, LLMs could return grammar analysis of Korean sentences using this format instead of JSON, enabling verification through TypeScript's type checker to improve correctness.
14+
15+
> 📖 **Want to learn more?** Check out our [detailed blog post](./blog.md) which explains how the TypeScript type system can be used to learn Korean grammar from the ground up. The article starts with basic programming concepts and gradually builds up to complex Korean grammatical structures like conditional sentences and interrogative phrases.
16+
17+
```typescript
18+
// Define the proper noun "ヒンメル"
19+
type ヒンメル = ProperNoun<"ヒンメル">;
20+
21+
// Define する verb
22+
type する = IrregularVerb & { dictionary: "する" };
23+
24+
// Create the そうした pattern (past form of そうする)
25+
type そうした = DemonstrativeAction<Demonstrative & "そう", する, "Ta">;
26+
27+
// Create the conditional phrase "ヒンメルならそうした"
28+
type ヒンメルならそうした = ConditionalPhrase<ヒンメル, "なら", そうした>;
29+
30+
// Type checking examples
31+
const properExample: ヒンメルならそうした = "ヒンメルならそうした"; // "If it were Himmel, he would do so"
32+
// 如果是辛美尔的话,他也会这么做的
33+
```
34+
35+
## 🤖 Verb System
36+
37+
### Verb Classes
38+
39+
Korean verbs are categorized into three main classes:
40+
41+
1. **Godan Verbs (五段動詞)** - Also known as "Group 1" or "u-verbs"
42+
43+
- Endings: う, く, ぐ, す, つ, ぬ, ぶ, む, る
44+
- Examples: 話す (hanasu - to speak), 書く (kaku - to write)
45+
46+
2. **Ichidan Verbs (一段動詞)** - Also known as "Group 2" or "ru-verbs"
47+
48+
- Always end with る
49+
- Examples: 食べる (taberu - to eat), 見る (miru - to see)
50+
51+
3. **Irregular Verbs (不規則動詞)** - Only two main verbs
52+
- する (suru - to do)
53+
- 来る (kuru - to come)
54+
55+
### Verb Conjugation Forms
56+
57+
The system supports these conjugation forms:
58+
59+
- Dictionary (Dictionary form)
60+
- Masu (Polite form)
61+
- Te (Te form)
62+
- Ta (Past form)
63+
- Nai (Negative form)
64+
- Potential (Potential form)
65+
- Passive (Passive form)
66+
- Causative (Causative form)
67+
- Volitional (Volitional form)
68+
- Imperative (Imperative form)
69+
- Conditional (Conditional form)
70+
- Hypothetical (Hypothetical form)
71+
72+
```typescript
73+
type 買う = GodanVerb & { stem: ""; ending: "" };
74+
type 買うTe = ConjugateVerb<買う, "Te">; // 買って
75+
type 買うTa = ConjugateVerb<買う, "Ta">; // 買った
76+
77+
type 食べる = IchidanVerb & { stem: "食べ"; ending: "" };
78+
type 食べるTe = ConjugateVerb<食べる, "Te">; // 食べて
79+
type 食べるTa = ConjugateVerb<食べる, "Ta">; // 食べた
80+
```
81+
82+
## 🎨 Adjective System
83+
84+
Korean adjectives are categorized into two main classes:
85+
86+
1. **I-Adjectives (い形容詞)** - End with い
87+
88+
- Examples: いい (good), 楽しい (fun), 高い (expensive)
89+
90+
2. **Na-Adjectives (な形容詞)** - Require な when modifying nouns
91+
- Examples: 綺麗 (pretty), 静か (quiet), 好き (liked)
92+
93+
### Adjective Conjugation Forms
94+
95+
The system supports these conjugation forms for adjectives:
96+
97+
- Basic (Basic form)
98+
- Polite (Polite form)
99+
- Past (Past form)
100+
- Negative (Negative form)
101+
102+
```typescript
103+
type いい = IAdjective & { stem: ""; ending: ""; irregular: true };
104+
type 綺麗 = NaAdjective & { stem: "綺麗" };
105+
```
106+
107+
## 🔗 Copula System
108+
109+
The copula (だ / です) turns a 体言 (noun or na-adjective stem) into a statement —
110+
"X is …". It is **not** a particle: like a verb or an adjective it inflects for
111+
politeness, tense and polarity, so it is modeled as a conjugable word via
112+
`ConjugateCopula<Taigen, Form>` (mirroring `ConjugateVerb` / `ConjugateAdjective`).
113+
114+
### Copula Conjugation Forms
115+
116+
- Plain → だ (plain) ・ Polite → です (polite)
117+
- Past → だった ・ PolitePast → でした
118+
- Negative → ではない ・ PoliteNegative → ではありません
119+
- NegativePast → ではなかった ・ PoliteNegativePast → ではありませんでした
120+
- CasualNegative → じゃない ・ CasualPoliteNegative → じゃありません
121+
- Written → である(formal written)・ Te → で(connective)
122+
123+
> The copula has no generic attributive form: な is licensed only for
124+
> な-adjectives (静かな町), never for plain nouns (×医者な — a noun takes の), so it
125+
> lives in the adjective system, not here.
126+
127+
```typescript
128+
type 医者だ = ConjugateCopula<"医者", "Plain">; // 医者だ
129+
type 医者ではありません = ConjugateCopula<"医者", "PoliteNegative">; // 医者ではありません
130+
```
131+
132+
## 📚 Phrase and Sentence Composition
133+
134+
The system now supports:
135+
136+
- Adjectives and verbs with particles
137+
- Connecting phrases with Korean punctuation
138+
- Basic sentence structures
139+
- Conditional expressions with particles like なら
140+
- Demonstrative forms with actions
141+
142+
Example: Connecting simple adjective and imperative verb phrases
143+
144+
```typescript
145+
// I-adjective "ii" (good) with irregular conjugation
146+
// Then add particle "yo" to basic form of "ii" -> "ii yo"
147+
type いい = IAdjective & { stem: ""; ending: ""; irregular: true };
148+
type いいよ = PhraseWithParticle<ConjugateAdjective<いい, "Basic">, "">;
149+
150+
// Irregular verb "kuru" (to come)
151+
// Then add particle "yo" to imperative form of "kuru" -> "koi yo"
152+
type 来る = IrregularVerb & { dictionary: "来る" };
153+
type 来いよ = PhraseWithParticle<ConjugateVerb<来る, "Imperative">, "">;
154+
155+
// Connect both phrases -> "ii yo, koi yo"
156+
type いいよ来いよ = ConnectedPhrases<いいよ, 来いよ>;
157+
158+
// Type checking examples
159+
const correctPhrase1: いいよ = "いいよ"; // "It's good!" (114)
160+
const correctPhrase2: 来いよ = "来いよ"; // "Come here!" (514)
161+
const correctFullPhrase: いいよ来いよ = "いいよ、来いよ"; // "It's good, come here!"
162+
```
163+
164+
Example: More flexible component-based sentence construction
165+
166+
```typescript
167+
type SentenceParts = [
168+
AdverbPart<"なんで">, // "Why" - question adverb
169+
IntensifierPart<"そんなに">, // "So much" - intensifier
170+
VerbPart<慣れる, "Te">, // "Get used to" in te-form
171+
ContractedPart<"">, // Contraction of "の" - colloquial nominalizer
172+
CopulaPart<"Plain">, // Copula "is" (だ) — a conjugable copula, not a particle
173+
ParticlePart<""> // Emphatic sentence-ending particle
174+
];
175+
176+
// Combines all parts into a single string
177+
type JoinedSentence = JoinPhrasePartsValue<SentenceParts>;
178+
const joinedSentence: JoinedSentence = "なんでそんなに慣れてんだよ"; // "Why are you so used to it?!"
179+
// 你为什么这么熟练啊?
180+
```
181+
182+
## ⚙️ Technical Implementation
183+
184+
The system uses TypeScript's template literal types, conditional types, and mapped types to create a purely type-level representation of Korean grammatical rules.
185+
186+
Key components:
187+
188+
- Type definitions for grammatical elements
189+
- Rule mapping via conditional types
190+
- String literal manipulation for form generation
191+
- Type inference for grammatical validation
192+
193+
## 💡 Why Typed Korean?
194+
195+
- **Educational tool** - Learn Korean grammar through code
196+
- **AI-assisted learning** - Provide structured formats for language analysis
197+
- **Grammar verification** - Express and verify Korean grammar in code
198+
- **Integration potential** - Basis for typed Korean language tools
199+
200+
## ⚠️ Limitations
201+
202+
- This is a type-level system only - it doesn't provide runtime functionality
203+
- The system handles standard forms but doesn't account for linguistic nuances
204+
- Some rare or archaic language patterns may not be accurately represented
205+
206+
This project is still in very early stages and heavily relies on LLM-generated grammar rules, which may occasionally contain hallucinations or inaccuracies. If you find any issue during actual use, please help by confirming and providing feedback.
207+
208+
## 🛠️ Development
209+
210+
If you're interested in contributing to or experimenting with Typed Korean:
211+
212+
1. Ensure you have [Node.js](https://nodejs.org/) and [pnpm](https://pnpm.io/) installed
213+
2. Clone the repository
214+
3. Install dependencies: `pnpm install`
215+
4. Run the tests: `pnpm test`
216+
217+
The tests validate that the type system functions correctly and all grammatical rules are properly implemented.
218+
219+
We welcome contributions! Feel free to open issues for bugs or feature requests, or submit pull requests with improvements.
220+
221+
## 📬 Contact
222+
223+
For sponsorship opportunities, research collaborations, or commercial inquiries, please reach out to `contact@typedgrammar.com`.
224+
225+
## ⚖️ License
226+
227+
[MIT](https://opensource.org/licenses/MIT)
228+
229+
Copyright (c) 2025-present, Yifeng Wang

0 commit comments

Comments
 (0)