TC39 프로세스와 최신 제안 — Decorators, Pipeline, Records & Tuples
자바스크립트의 새 기능은 갑자기 나타나는 것이 아니라, TC39라는 위원회의 엄격한 프로세스를 거칩니다. 이 프로세스를 이해하면 "이 문법 쓸 수 있나요?"라는 질문에 정확히 답할 수 있습니다.
TC39 프로세스
| 단계 | 이름 | 의미 |
|---|---|---|
| Stage 0 | Strawperson | 아이디어 제안 |
| Stage 1 | Proposal | 문제 정의 + 초안 |
| Stage 2 | Draft | 정식 스펙 초안 |
| Stage 2.7 | - | 구현 시작 가능 |
| Stage 3 | Candidate | 검증 단계, 브라우저 구현 시작 |
| Stage 4 | Finished | 표준 확정, 다음 ES 버전에 포함 |
Stage 3에 도달하면 메이저 변경 없이 표준에 포함될 가능성이 높습니다.
Decorators (Stage 3)
클래스와 클래스 멤버에 메타 프로그래밍 기능을 추가합니다.
// 데코레이터 정의
function logged(value, context) {
if (context.kind === "method") {
return function (...args) {
console.log(`호출: ${context.name}(${args.join(", ")})`);
const result = value.call(this, ...args);
console.log(`결과: ${result}`);
return result;
};
}
}
function readonly(value, context) {
if (context.kind === "field") {
return function (initialValue) {
return initialValue;
};
}
// accessor에 적용 시 set을 막음
}
// 사용
class Calculator {
@logged
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
calc.add(2, 3);
// 호출: add(2, 3)
// 결과: 5
데코레이터의 종류
// 클래스 데코레이터
@injectable
class UserService {}
// 메서드 데코레이터
class API {
@cache(60)
async fetchData() {}
}
// 필드 데코레이터
class Model {
@validate({ min: 0, max: 100 })
age = 25;
}
// 접근자 데코레이터
class User {
@bound
accessor name = "정훈";
}
Pipeline Operator (Stage 2)
함수 호출을 체이닝할 수 있는 연산자입니다.
// 현재 — 중첩 함수 호출 (안쪽부터 읽어야 함)
const result = capitalize(trim(sanitize(input)));
// Pipeline Operator — 왼쪽에서 오른쪽으로 읽기
const result = input
|> sanitize(%)
|> trim(%)
|> capitalize(%);
// 실전 예시
const processedUsers = users
|> filter(%, (u) => u.active)
|> map(%, (u) => u.name)
|> sort(%)
|> join(%, ", ");
Records & Tuples (Stage 2)
깊은 불변 데이터 구조입니다.
// Record — 불변 객체 (# 접두사)
const user = #{ name: "정훈", age: 25 };
// user.name = "길동"; // TypeError — 불변!
// Tuple — 불변 배열
const colors = #["red", "green", "blue"];
// colors.push("yellow"); // TypeError — 불변!
// 값 비교 (=== 사용 가능!)
#{ a: 1, b: 2 } === #{ a: 1, b: 2 }; // true!
// 일반 객체는 false: { a: 1 } === { a: 1 } // false
// 중첩도 불변
const nested = #{ user: #{ name: "정훈" }, scores: #[90, 95] };
// Map/Set의 키로 사용 가능
const map = new Map();
map.set(#{ x: 1, y: 2 }, "point");
map.get(#{ x: 1, y: 2 }); // "point" — 값으로 비교!
최근 확정된 기능들
// Array.fromAsync (ES2024)
const arr = await Array.fromAsync(asyncIterable);
// Object.groupBy (ES2024)
const grouped = Object.groupBy(users, (u) => u.role);
// { admin: [...], user: [...] }
// Promise.withResolvers (ES2024)
const { promise, resolve, reject } = Promise.withResolvers();
// Set 메서드 (ES2025)
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
a.union(b); // Set {1, 2, 3, 4}
a.intersection(b); // Set {2, 3}
// Iterator Helpers (ES2025)
const evens = Iterator.from([1, 2, 3, 4, 5, 6])
.filter((n) => n % 2 === 0)
.map((n) => n * 10)
.toArray(); // [20, 40, 60]
제안 추적 방법
GitHub: https://github.com/tc39/proposals
- Stage 0: https://github.com/tc39/proposals/blob/main/stage-0-proposals.md
- Stage 1-3: README.md
- Finished: finished-proposals.md
Can I Use: 브라우저 지원 현황 확인
Babel: Stage 3 이상은 대부분 Babel 플러그인 존재
TypeScript: Stage 3 제안 중 일부를 먼저 지원하기도 함
**기억하기 **: TC39의 Stage 3은 "거의 확정"을 의미합니다. Decorators는 메타 프로그래밍, Pipeline은 함수 체이닝, Records & Tuples는 불변 데이터 구조를 위한 제안입니다.
Object.groupBy,Set.union같은 최신 기능들은 이미 대부분의 브라우저에서 사용 가능합니다.
댓글 로딩 중...