๋ฐฐ์ด/๊ฐ์ฒด ์กฐ์, ๋น๋๊ธฐ Promise/Async ํจํด, TypeScript ํต์ฌ ์ ํธ๋ฆฌํฐ ํ์
๋ฐ ์ค์ ํ
## 1. ๋ฐฐ์ด ๊ณ ๊ธ ๋ค๋ฃจ๊ธฐ (Array Methods)
```typescript
// ์ค๋ณต ์ ๊ฑฐ (Set ํ์ฉ)
const uniqueList = [...new Set([1, 2, 2, 3, 4, 4])];
// ํค ๊ธฐ์ค์ผ๋ก ๊ฐ์ฒด ๋ฐฐ์ด ๊ทธ๋ฃนํ (ES2024 Object.groupBy)
const grouped = Object.groupBy(items, item => item.category);
// ํํํ ๋ฐ ๋งคํ (flatMap)
const tags = posts.flatMap(post => post.tags);
// ํน์ ์กฐ๊ฑด ๋ง์กฑ ์ฌ๋ถ ๊ฒ์ฌ
const hasAdmin = users.some(u => u.role === 'admin');
const allVerified = users.every(u => u.isVerified);
```
## 2. ๊ฐ์ฒด ๊ตฌ์กฐ๋ถํด & ๋ ๋ณํฉ
```typescript
// ๊ธฐ๋ณธ๊ฐ ์ง์ ๋ฐ ์ด๋ฆ ๋ณ๊ฒฝ ๊ตฌ์กฐ๋ถํด
const { name: userName, age = 20 } = user;
// ์ต์
๋ ์ฒด์ด๋ & ๋ ๋ณํฉ ์ฐ์ฐ์ (?? vs ||)
// ?? ๋ null ๋๋ undefined ์ผ ๋๋ง ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉ (0, '' ์ ์ ์ง)
const port = process.env.PORT ?? 3000;
const street = user?.address?.street ?? '์ฃผ์ ๋ฏธ์
๋ ฅ';
// ๊ฐ์ฒด ๋์ ํค ์ถ๊ฐ
const dynamicObj = {
[dynamicKey]: 'value',
...(isAdmin && { permissions: ['ALL'] }),
};
```
## 3. ๋น๋๊ธฐ ์ ์ด & Promise ๋ณ๋ ฌ ์ฒ๋ฆฌ
```typescript
// ์ฌ๋ฌ ๋น๋๊ธฐ ์์
๋์ ๋ณ๋ ฌ ์คํ (ํ๋๋ผ๋ ์คํจํ๋ฉด ์ค๋จ)
const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
// ๋ชจ๋ ์์
์ ์ฑ๊ณต/์คํจ ์ฌ๋ถ๋ฅผ ๋๊น์ง ์ง๊ณ
const results = await Promise.allSettled(urls.map(fetchData));
results.forEach(res => {
if (res.status === 'fulfilled') console.log(res.value);
else console.error(res.reason);
});
// ํ์์์์ ์ง์ํ๋ ๋น๋๊ธฐ ๋ํผ
const timeout = (ms: number) => new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout!')), ms)
);
await Promise.race([fetchData(), timeout(5000)]);
```
## 4. TypeScript ํ์ ์ ํธ๋ฆฌํฐ ํ์
```typescript
interface User {
id: string;
name: string;
email: string;
avatarUrl?: string;
}
// ๋ชจ๋ ์์ฑ์ ์ ํ(optional)์ผ๋ก ๋ง๋ค๊ธฐ
type PartialUser = Partial<User>;
// ํน์ ์์ฑ๋ง ๊ณจ๋ผ๋ด๊ธฐ
type UserPreview = Pick<User, 'id' | 'name'>;
// ํน์ ์์ฑ๋ง ์ ์ธํ๊ธฐ
type UserWithoutId = Omit<User, 'id'>;
// ๋ชจ๋ ์์ฑ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ง๋ค๊ธฐ
type ReadonlyUser = Readonly<User>;
// Record ํ์
(ํค์ ๊ฐ ํ์
๋งตํ)
type RoleMap = Record<string, string[]>;
```
## 5. ํ์
๊ฐ๋ (Type Narrowing)
```typescript
// ์ฌ์ฉ์ ์ ์ ํ์
๊ฐ๋ (is ์ฐ์ฐ์)
function isError(value: unknown): value is Error {
return value instanceof Error;
}
// ์๋ณ ๊ฐ๋ฅํ ์ ๋์จ (Discriminated Union)
type ApiResponse =
| { status: 'success'; data: User }
| { status: 'error'; message: string };
function handleResponse(res: ApiResponse) {
if (res.status === 'success') {
console.log(res.data.name); // ํ์
์์ ๋ณด์ฅ
} else {
console.error(res.message);
}
}
```
## 6. ํด๋ก์ & ๋๋ฐ์ด์ค ์ ํธ๋ฆฌํฐ
```typescript
// ๊ฒ์์ฐฝ ์
๋ ฅ ์ง์ฐ ์ฒ๋ฆฌ์ฉ ๋๋ฐ์ด์ค(Debounce)
function debounce<T extends (...args: any[]) => any>(
fn: T,
delay: number
) {
let timer: NodeJS.Timeout;
return (...args: Parameters<T>) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
```
์๊ฒฌ ๋ฐ ์ง๋ฌธ
0์์ง ๋ฑ๋ก๋ ์๊ฒฌ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋๊ธ์ ๋จ๊ฒจ๋ณด์ธ์!
๋๊ธ ์์
๋๊ธ ์ญ์