Skip to content

Commit aa1794e

Browse files
committed
docs: Claude code 사용
1 parent 6beda12 commit aa1794e

4 files changed

Lines changed: 396 additions & 0 deletions

File tree

.claude/skills/add-type/SKILL.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Skill: add-type
2+
3+
## 역할
4+
5+
DeepStrictTypes 라이브러리에 새로운 유틸리티 타입 또는 런타임 함수를 추가하는 전문가입니다.
6+
7+
## 트리거 조건
8+
9+
- 새로운 유틸리티 타입 설계/구현 요청
10+
- 기존 타입의 확장이나 변형 타입 추가
11+
- 새로운 런타임 함수 추가
12+
13+
## 실행 모드
14+
15+
**Plan Mode** - 구현 전 사용자 승인 필수
16+
17+
## 워크플로우
18+
19+
### 1단계: 설계 분석
20+
21+
- 요청된 타입/함수의 목적과 시그니처 정의
22+
- 기존 타입과의 관계 파악 (의존성, 유사성)
23+
- 입출력 예시 3개 이상 정의
24+
25+
### 2단계: 기존 패턴 확인
26+
27+
반드시 다음을 확인합니다:
28+
29+
```
30+
src/types/ # 기존 타입들의 구현 패턴
31+
src/functions/ # 기존 함수들의 구현 패턴
32+
test/features/ # 기존 테스트 패턴
33+
```
34+
35+
### 3단계: 구현 계획
36+
37+
1. **타입 파일 생성**: `src/types/<TypeName>.ts` 또는 `src/functions/<FunctionName>.ts`
38+
2. **테스트 파일 생성**: `test/features/<TypeName>.ts`
39+
3. **index.ts 업데이트**: `src/types/index.ts` 또는 `src/functions/index.ts`에 re-export 추가
40+
41+
### 4단계: 구현
42+
43+
#### 타입 파일 템플릿
44+
45+
```typescript
46+
import type { DeepStrictObjectKeys } from './DeepStrictObjectKeys';
47+
// 필요한 의존 타입 import
48+
49+
/**
50+
* @title <타입의 한 줄 설명>
51+
*
52+
* <상세 설명 - 무엇을 하는 타입인지, 왜 필요한지>
53+
*
54+
* {@link DeepStrictObjectKeys} can be used to determine valid keys.
55+
*
56+
* Example Usage:
57+
* ```ts
58+
* type Example1 = <TypeName><...>; // 결과
59+
* type Example2 = <TypeName><...>; // 결과
60+
* ```
61+
*/
62+
export type <TypeName><T extends object, ...> = ...;
63+
```
64+
65+
#### 테스트 파일 템플릿
66+
67+
```typescript
68+
import { ok } from 'assert';
69+
import typia from 'typia';
70+
import { <TypeName>, Equal } from '../../src';
71+
72+
/**
73+
* Tests that <TypeName> correctly handles <scenario>.
74+
*/
75+
export function test_types_<snake_case_name>_<scenario>() {
76+
type Question = <TypeName><InputType, Key>;
77+
type Answer = Equal<Question, ExpectedType>;
78+
ok(typia.random<Answer>());
79+
}
80+
```
81+
82+
### 5단계: 검증
83+
84+
```bash
85+
npm run build:test && npm run test -- --include <TypeName>
86+
```
87+
88+
## 체크리스트
89+
90+
- [ ] JSDoc에 `@title`, 설명, 예시 코드 포함 (영어)
91+
- [ ] Date 타입을 object로 재귀 탐색하지 않도록 처리
92+
- [ ] 배열 타입에 대한 `[*]` 표기 지원
93+
- [ ] namespace로 내부 추론 타입 분리 (복잡한 경우)
94+
- [ ] 테스트 함수에 export 키워드 포함
95+
- [ ] 테스트가 최소 3개 이상의 시나리오 커버
96+
- [ ] `src/types/index.ts` 또는 `src/functions/index.ts`에 re-export 추가
97+
- [ ] `npm run build:test && npm run test` 통과

.claude/skills/fix-type/SKILL.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Skill: fix-type
2+
3+
## 역할
4+
5+
기존 유틸리티 타입의 버그를 진단하고 수정하는 전문가입니다. 타입 레벨 버그는 재현이 어렵기 때문에 체계적인 접근이 필요합니다.
6+
7+
## 트리거 조건
8+
9+
- 특정 입력에서 타입 추론이 잘못되는 경우
10+
- 타입 에러가 발생하거나 `never`로 추론되는 경우
11+
- edge case (빈 객체, 깊은 중첩, readonly 배열 등) 처리 실패
12+
13+
## 실행 모드
14+
15+
**Plan Mode** - 수정 전 사용자 승인 필수
16+
17+
## 워크플로우
18+
19+
### 1단계: 버그 재현
20+
21+
- 문제가 되는 타입 표현식을 `Equal<>` 타입으로 검증
22+
- 기대 결과와 실제 결과를 명확히 정의
23+
- 테스트 파일에 실패 케이스 추가
24+
25+
### 2단계: 원인 분석
26+
27+
- 타입의 조건부 분기를 단계별로 추적
28+
- 어떤 분기에서 잘못된 추론이 발생하는지 특정
29+
- 관련 의존 타입들도 함께 확인
30+
31+
### 3단계: 수정
32+
33+
- 최소한의 변경으로 수정 (기존 동작을 깨트리지 않도록)
34+
- 수정 후 기존 테스트 전체 통과 확인
35+
- 새로운 edge case 테스트 추가
36+
37+
### 4단계: 검증
38+
39+
```bash
40+
# 전체 테스트 실행 (기존 동작 보존 확인)
41+
npm run build:test && npm run test
42+
43+
# 특정 타입만 테스트
44+
npm run build:test && npm run test -- --include <TypeName>
45+
```
46+
47+
## 체크리스트
48+
49+
- [ ] 버그 재현 테스트 케이스 작성
50+
- [ ] 기존 테스트 전체 통과 확인
51+
- [ ] 수정 후 edge case 테스트 추가
52+
- [ ] JSDoc 예시가 수정 사항을 반영하는지 확인

.claude/skills/write-test/SKILL.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Skill: write-test
2+
3+
## 역할
4+
5+
DeepStrictTypes의 타입과 함수에 대한 테스트를 작성하는 전문가입니다.
6+
7+
## 트리거 조건
8+
9+
- 새 타입/함수에 대한 테스트 추가
10+
- 기존 테스트 보강 (edge case 추가)
11+
- 버그 리포트에 대한 재현 테스트
12+
13+
## 실행 모드
14+
15+
**Plan Mode** - 작성 전 사용자 승인 필수
16+
17+
## 테스트 프레임워크
18+
19+
`@nestia/e2e``DynamicExecutor`를 사용합니다. `test/features/` 디렉토리에서 `test_` prefix가 붙은 **export** 함수를 자동 수집하여 실행합니다.
20+
21+
**Jest/Mocha/Vitest 등을 사용하지 않습니다.**
22+
23+
## 테스트 패턴
24+
25+
### 타입 테스트 (type-level)
26+
27+
```typescript
28+
import { ok } from 'assert';
29+
import typia from 'typia';
30+
import { TargetType, Equal } from '../../src';
31+
32+
/**
33+
* Tests that TargetType correctly handles <scenario>.
34+
*/
35+
export function test_types_<snake_case_name>_<scenario>() {
36+
type Question = TargetType<InputType, Key>;
37+
type Answer = Equal<Question, ExpectedType>;
38+
ok(typia.random<Answer>());
39+
}
40+
```
41+
42+
핵심: `Equal<A, B>`는 두 타입이 동일하면 `true` 리터럴 타입, 다르면 `false` 리터럴 타입을 반환합니다. `typia.random<true>()`는 항상 `true`를 반환하므로 `ok()`를 통과하고, `typia.random<false>()``false`를 반환하므로 실패합니다.
43+
44+
### 함수 테스트 (runtime)
45+
46+
```typescript
47+
import { ok, deepStrictEqual } from 'assert';
48+
import { deepStrictAssert } from '../../src';
49+
50+
/**
51+
* Tests that deepStrictAssert correctly extracts <scenario>.
52+
*/
53+
export function test_functions_<snake_case_name>_<scenario>() {
54+
const input = { a: { b: 1, c: 2 } };
55+
const result = deepStrictAssert(input)("a.b");
56+
deepStrictEqual(result, { a: { b: 1 } });
57+
}
58+
```
59+
60+
## 명명 규칙
61+
62+
| 대상 | 함수명 패턴 | 예시 |
63+
|------|-------------|------|
64+
| 타입 | `test_types_<snake_case_name>_<scenario>` | `test_types_deep_strict_pick_nested_array` |
65+
| 함수 | `test_functions_<snake_case_name>_<scenario>` | `test_functions_deep_strict_assert_basic` |
66+
67+
## 필수 시나리오
68+
69+
새 타입을 테스트할 때 최소한 다음 시나리오를 커버합니다:
70+
71+
1. **기본 동작** - 가장 단순한 사용법
72+
2. **중첩 객체** - 2단계 이상 중첩
73+
3. **배열 포함** - `[*]` 표기가 필요한 경우
74+
4. **배열 내 중첩** - `a[*].b[*].c` 같은 복합 경로
75+
5. **edge case** - 빈 객체, 단일 프로퍼티, Date 타입 등
76+
77+
## 실행 및 검증
78+
79+
```bash
80+
# 전체 테스트
81+
npm run build:test && npm run test
82+
83+
# 특정 테스트만
84+
npm run build:test && npm run test -- --include <TypeName>
85+
```
86+
87+
## 체크리스트
88+
89+
- [ ] 모든 테스트 함수에 `export` 키워드
90+
- [ ] 모든 테스트 함수에 JSDoc 설명 (영어)
91+
- [ ] 함수명이 `test_types_` 또는 `test_functions_`로 시작
92+
- [ ] 파라미터 없는 함수 (DynamicExecutor 규약)
93+
- [ ] 최소 3개 이상의 시나리오
94+
- [ ] `npm run build:test && npm run test` 통과

CLAUDE.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
`@kakasoo/deep-strict-types`는 중첩된 배열과 객체 내부의 키를 타입 안전하게 Pick, Omit, 탐색할 수 있는 TypeScript 유틸리티 타입 라이브러리입니다.
8+
9+
npm 패키지로 배포되며, 순수 타입 수준(type-level)의 연산과 런타임 함수를 모두 제공합니다.
10+
11+
## Build & Test Commands
12+
13+
```bash
14+
# 빌드
15+
npm run build # rimraf bin && tsc (src만 빌드)
16+
npm run build:test # rimraf bin && tsc -p test/tsconfig.json (테스트 포함 빌드)
17+
18+
# 테스트 (빌드 후 실행)
19+
npm run build:test && npm run test
20+
21+
# 특정 테스트만 실행
22+
npm run build:test && npm run test -- --include DeepStrictPick
23+
24+
# 포매팅
25+
npm run prettier
26+
27+
# typia 패치 (최초 세팅)
28+
npm run prepare # ts-patch install && typia patch
29+
```
30+
31+
### 테스트 실행 방식
32+
33+
테스트는 `@nestia/e2e``DynamicExecutor`를 사용합니다. `test/features/` 디렉토리에서 `test_` prefix가 붙은 export 함수를 자동으로 수집하여 실행합니다. **Jest/Mocha 등의 테스트 프레임워크를 사용하지 않습니다.**
34+
35+
## Architecture
36+
37+
```
38+
src/
39+
types/ # 순수 타입 정의 (type-level 연산)
40+
functions/ # 런타임 함수 (타입과 연동)
41+
index.ts # re-export
42+
43+
test/
44+
features/ # 테스트 파일 (test_types_*, test_functions_*)
45+
helpers/ # 테스트 유틸리티
46+
index.ts # DynamicExecutor 기반 테스트 러너
47+
```
48+
49+
### 핵심 타입
50+
51+
| 타입 | 역할 |
52+
|------|------|
53+
| `DeepStrictObjectKeys<T>` | 중첩 객체의 모든 키를 dot notation으로 추출 (`a.b`, `c[*].d`) |
54+
| `DeepStrictOmit<T, K>` | 중첩 키를 기준으로 deep omit |
55+
| `DeepStrictPick<T, K>` | 중첩 키를 기준으로 deep pick |
56+
| `DeepStrictMerge<T, U>` | 두 객체를 deep merge |
57+
| `DeepDateToString<T>` | Date 타입을 string으로 재귀 변환 |
58+
| `DeepStrictUnbrand<T>` | 브랜드 타입 제거 |
59+
| `Equal<A, B>` | 두 타입의 동등성 검사 (테스트용) |
60+
61+
### 핵심 함수
62+
63+
| 함수 | 역할 |
64+
|------|------|
65+
| `deepStrictAssert<T>(input)<K>(key)` | 런타임에서 특정 키만 추출 (타입 안전) |
66+
| `deepStrictObjectKeys<T>(input)` | 런타임에서 모든 중첩 키 문자열 배열 반환 |
67+
68+
## Coding Conventions
69+
70+
### 타입 작성 규칙
71+
72+
1. **PascalCase** 사용 (예: `DeepStrictPick`, `RemoveAfterDot`)
73+
2. **JSDoc 필수** - 모든 export 타입에 `@title`, 설명, 예시 코드 포함
74+
3. **JSDoc은 영어로 작성** - npm 패키지의 국제적 사용을 고려
75+
4. **타입 간 의존성은 import type 사용**
76+
5. **namespace를 활용한 내부 타입 구조화** - 외부 노출 타입과 내부 추론 타입 분리 (예: `DeepStrictOmit.Infer`)
77+
6. **`[*]` 표기법** - 배열 내부 접근 시 사용 (예: `c[*].d`)
78+
7. **Date 타입 특별 처리** - object이지만 재귀 탐색하지 않음
79+
80+
### 파일 구조 규칙
81+
82+
- 하나의 타입/함수 = 하나의 파일 (파일명 = 타입명)
83+
- `index.ts`에서 모든 public 타입/함수를 re-export
84+
- 새 타입/함수 추가 시 반드시 `src/types/index.ts` 또는 `src/functions/index.ts`에 export 추가
85+
86+
### 테스트 규칙
87+
88+
- **함수명**: `test_types_<type_name>_<scenario>` 또는 `test_functions_<func_name>_<scenario>`
89+
- **반드시 export** (DynamicExecutor가 수집하기 위해)
90+
- **파라미터 없음** (M24과 달리 TestOption을 받지 않음)
91+
- **검증 방법**: `Equal<Question, Answer>` 타입으로 타입 레벨 검증 + `typia.random<Answer>()`로 런타임 확인
92+
- **파일명**: 테스트 대상 타입/함수와 동일한 이름
93+
- **하나의 파일에 여러 테스트 함수** 가능 (시나리오별 분리)
94+
95+
### 테스트 패턴
96+
97+
```typescript
98+
import { ok } from 'assert';
99+
import typia from 'typia';
100+
import { DeepStrictPick, Equal } from '../../src';
101+
102+
export function test_types_deep_strict_pick_nested() {
103+
type Question = DeepStrictPick<{ a: { b: 1; c: 2 } }, "a.b">;
104+
type Answer = Equal<Question, { a: { b: 1 } }>;
105+
ok(typia.random<Answer>());
106+
}
107+
```
108+
109+
## Git Conventions
110+
111+
### 브랜치 규칙
112+
113+
- 기본 브랜치: `main`
114+
- 기능 브랜치: `feature/<name>`, `fix/<name>`, `docs/<name>`
115+
116+
### 커밋 메시지
117+
118+
영어로 작성하며 다음 prefix를 사용합니다:
119+
120+
| Prefix | 용도 |
121+
|--------|------|
122+
| `feat` | 새로운 타입/함수 추가 |
123+
| `fix` | 타입 버그 수정 |
124+
| `test` | 테스트 추가/수정 |
125+
| `docs` | 문서/주석 변경 |
126+
| `refactor` | 리팩토링 |
127+
| `style` | 코드 포맷팅 |
128+
| `chore` | 빌드, 설정 변경 |
129+
130+
형식: `<prefix>: <영어 설명>`
131+
132+
## CI/CD
133+
134+
- main 브랜치에 push + `src/` 또는 `package.json` 변경 시 자동으로:
135+
1. npm install + build
136+
2. `npm version patch` (자동 버전 증가)
137+
3. npm publish
138+
4. git push --follow-tags
139+
140+
## Dependencies
141+
142+
- **런타임**: `@kakasoo/proto-typescript` (프로토타입 유틸리티)
143+
- **개발**: `typia` (런타임 검증/랜덤 생성), `@nestia/e2e` (테스트 러너), `ts-patch` (typia 트랜스폼)
144+
145+
## 비판적 피드백 원칙
146+
147+
사용자의 요청이 다음에 해당하면 **즉시 지적하고 대안을 제시**합니다:
148+
149+
- 타입 레벨 연산에서 `any`, `as` 캐스팅 사용 시도
150+
- Utility Type (`Partial`, `Pick`, `Omit` 등) 직접 사용 (이 라이브러리가 deep 버전을 제공)
151+
- Date를 일반 object처럼 재귀 탐색하려는 시도
152+
- 테스트 없이 새 타입 추가 시도
153+
- `index.ts` re-export 누락

0 commit comments

Comments
 (0)