@choblue/claude-code-toolkit 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/code-reviewer.md +8 -0
- package/.claude/agents/code-writer-be.md +8 -0
- package/.claude/agents/code-writer-fe.md +8 -0
- package/.claude/agents/explore.md +8 -0
- package/.claude/agents/git-manager.md +8 -0
- package/.claude/agents/test-writer-be.md +8 -0
- package/.claude/agents/test-writer-fe.md +8 -0
- package/.claude/skills/Coding/SKILL.md +5 -0
- package/.claude/skills/NextJS/SKILL.md +5 -0
- package/.claude/skills/React/SKILL.md +5 -0
- package/.claude/skills/ReactHookForm/SKILL.md +5 -0
- package/.claude/skills/TDD/SKILL.md +5 -0
- package/.claude/skills/TailwindCSS/SKILL.md +5 -0
- package/.claude/skills/TanStackQuery/SKILL.md +5 -0
- package/.claude/skills/TypeORM/SKILL.md +16 -303
- package/.claude/skills/TypeORM/references/advanced-queries.md +176 -0
- package/.claude/skills/TypeORM/references/migrations.md +62 -0
- package/.claude/skills/TypeORM/references/transactions.md +76 -0
- package/.claude/skills/TypeScript/SKILL.md +17 -225
- package/.claude/skills/TypeScript/references/advanced-patterns.md +146 -0
- package/.claude/skills/TypeScript/references/generics.md +98 -0
- package/.claude/skills/TypeScript/references/type-guards.md +109 -0
- package/.claude/skills/Zustand/SKILL.md +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# 타입 가드 (Type Guards)
|
|
2
|
+
|
|
3
|
+
이 문서는 TypeScript 타입 가드의 상세 패턴을 다룬다.
|
|
4
|
+
기본 규칙은 [SKILL.md](../SKILL.md)를 참고한다.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## is 키워드 (사용자 정의 타입 가드)
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
interface Admin {
|
|
12
|
+
role: 'admin';
|
|
13
|
+
permissions: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Guest {
|
|
17
|
+
role: 'guest';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type AppUser = Admin | Guest;
|
|
21
|
+
|
|
22
|
+
// Bad - 타입 단언
|
|
23
|
+
function getPermissions(user: AppUser): string[] {
|
|
24
|
+
return (user as Admin).permissions ?? [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Good - 타입 가드
|
|
28
|
+
function isAdmin(user: AppUser): user is Admin {
|
|
29
|
+
return user.role === 'admin';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getPermissions(user: AppUser): string[] {
|
|
33
|
+
if (isAdmin(user)) {
|
|
34
|
+
return user.permissions; // Admin으로 좁혀짐
|
|
35
|
+
}
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## in 연산자
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
interface Dog {
|
|
46
|
+
bark: () => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface Cat {
|
|
50
|
+
meow: () => void;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type Pet = Dog | Cat;
|
|
54
|
+
|
|
55
|
+
function makeSound(pet: Pet): void {
|
|
56
|
+
if ('bark' in pet) {
|
|
57
|
+
pet.bark(); // Dog으로 좁혀짐
|
|
58
|
+
} else {
|
|
59
|
+
pet.meow(); // Cat으로 좁혀짐
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Discriminated Union (태그드 유니언)
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// 공통 판별 필드(type)를 가진 유니언
|
|
70
|
+
type Shape =
|
|
71
|
+
| { type: 'circle'; radius: number }
|
|
72
|
+
| { type: 'rectangle'; width: number; height: number }
|
|
73
|
+
| { type: 'triangle'; base: number; height: number };
|
|
74
|
+
|
|
75
|
+
function calculateArea(shape: Shape): number {
|
|
76
|
+
switch (shape.type) {
|
|
77
|
+
case 'circle':
|
|
78
|
+
return Math.PI * shape.radius ** 2;
|
|
79
|
+
case 'rectangle':
|
|
80
|
+
return shape.width * shape.height;
|
|
81
|
+
case 'triangle':
|
|
82
|
+
return (shape.base * shape.height) / 2;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Exhaustive Check (never를 이용한 완전성 검사)
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// 모든 케이스를 처리했는지 컴파일 타임에 검증한다
|
|
93
|
+
function assertNever(value: never): never {
|
|
94
|
+
throw new Error(`Unexpected value: ${value}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getShapeLabel(shape: Shape): string {
|
|
98
|
+
switch (shape.type) {
|
|
99
|
+
case 'circle':
|
|
100
|
+
return '원';
|
|
101
|
+
case 'rectangle':
|
|
102
|
+
return '직사각형';
|
|
103
|
+
case 'triangle':
|
|
104
|
+
return '삼각형';
|
|
105
|
+
default:
|
|
106
|
+
return assertNever(shape); // 새로운 Shape 추가 시 컴파일 에러 발생
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|