TypeScript 와 strict 모드
TypeScript 와 strict 모드
TypeScript 는 JavaScript 에 정적 타입을 더한 언어. 이 글은 TypeScript 의 출자 · 동작 방식과 strict: true 옵션이 실제로 켜는 것들을 사실 기준으로 정리. 런타임 검증의 빈자리와 비슷한 도구의 위치도 함께.
1. TypeScript 에 대한 이야기
Microsoft 의 Anders Hejlsberg (Turbo Pascal · Delphi · C# 의 설계자로 알려진 인물) 가 주도해 만든 언어. 첫 공개는 2012 년 10 월이고, 1.0 은 2014 년 4 월. 저장소는 microsoft/TypeScript, 라이선스는 Apache-2.0.
언어 자체는 JavaScript 의 상위 집합 (superset) 으로 설계. 모든 유효한 JS 는 유효한 TS 이며, 컴파일러는 타입 정보를 제거한 JS 로 출력. 즉 TS 의 타입은 컴파일 타임에만 존재하고 런타임에는 흔적이 거의 남지 않습니다 (예외: enum · namespace 같은 일부 산출물).
배포물은 두 가지 — 컴파일러 tsc 와 언어 서버 tsserver. 후자가 VS Code · WebStorm 등에서 자동완성 · 오류표시를 담당.
2. 구조적 타이핑
TypeScript 의 타입 시스템은 structural typing (구조적 타이핑). Java · C# 의 명목적 타이핑 (nominal typing) 과 달리 두 타입의 호환은 이름이 아니라 모양 으로 판단:
interface Point { x: number; y: number }
function len(p: Point) { return Math.hypot(p.x, p.y) }
const p = { x: 3, y: 4, label: "a" } // Point 라 선언 안 했지만
len(p) // 모양이 맞으면 통과
3. strict: true 가 켜는 것
tsconfig.json 에 "strict": true 한 줄을 켜면 다음 옵션 묶음이 한꺼번에 (공식 문서 Strict Mode Family):
| 옵션 | 의미 |
|---|---|
noImplicitAny |
추론이 실패해 암묵적 any 가 되는 경우를 오류로 봄. |
strictNullChecks |
null 과 undefined 가 모든 타입에 자동 포함되지 않음. 의도한 곳만 T | null. |
strictFunctionTypes |
함수 매개변수의 반공변 (contravariant) 검사를 엄격히. |
strictBindCallApply |
bind · call · apply 의 인자 타입을 검사. |
strictPropertyInitialization |
클래스 필드가 생성자에서 반드시 초기화되도록 강제 (strictNullChecks 필요). |
alwaysStrict |
출력 JS 파일 상단에 "use strict" 를 자동으로 붙이고, 분석도 strict 모드. |
useUnknownInCatchVariables |
try { } catch (e) 의 e 기본 타입이 any 가 아닌 unknown. |
이 가운데 strictNullChecks 한 가지가 가장 큰 가치를 만든다는 평이 흔함. null / undefined 관련 런타임 오류를 컴파일 시점으로 옮김.
4. 제네릭 · 조건부 · 매핑 타입
// 제네릭
function first<T>(arr: T[]): T | undefined { return arr[0] }
// 매핑 타입
type Partial<T> = { [K in keyof T]?: T[K] }
// 조건부 타입
type NonNull<T> = T extends null | undefined ? never : T
infer · keyof · 템플릿 리터럴 타입까지 결합하면 타입 수준에서 작은 함수형 언어 가 동작한다고 표현.
5. 다른 길
| 도구 | 위치 | 비고 |
|---|---|---|
| TypeScript | Microsoft, 2012 | 사실상 표준. tsc 가 검사 + 트랜스파일. |
| Flow | Meta, 2014 | 비슷한 시도. 현재 Meta 내부 위주. Hermes 엔진과 결합. |
JSDoc + // @ts-check |
1995 (JSDoc) | 빌드 도구 없이 JS 파일에 타입을. tsc 가 읽을 수 있음. |
| esbuild · swc · Babel | 별도 | 타입 검사 안 함. 타입 정보를 제거 만 (빠름). 검사는 tsc --noEmit 별도. |
esbuild · swc 는 의도적으로 타입을 검사하지 않고 지움. 대규모 코드베이스에서 빌드와 검사를 분리해 빌드는 빠른 도구로, 검사는 tsc --noEmit 으로 돌리는 구성이 흔합니다.
6. tsconfig 출발점
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"skipLibCheck": true,
"esModuleInterop": true
}
}
noUncheckedIndexedAccess 와 exactOptionalPropertyTypes 는 strict 묶음에 들어가지 않지만 별도로 켜는 편이 흔함.
7. 런타임 검증과 zod
타입은 컴파일 시점에만 살아 있음. 외부에서 들어온 JSON · 폼 입력 · 환경변수는 런타임에 따로 검증해야 함. 이 자리에 자주 쓰이는 라이브러리:
import { z } from "zod"
const User = z.object({
id: z.string().uuid(),
email: z.string().email(),
age: z.number().int().nonnegative()
})
type User = z.infer<typeof User> // 정적 타입 자동 추출
const u = User.parse(jsonFromApi) // 실패 시 throw
zod (Colin McDonnell, 2020) 외에도 valibot · ArkType · yup · joi 가 같은 자리.
| 라이브러리 | 첫 공개 | 비고 |
|---|---|---|
| zod | 2020 | TS-first. 가장 넓게 채택. |
| yup | 2015 | Form 검증으로 시작. Formik 과 함께 자주. |
| joi | 2012 | 본래 hapi 서버용. 노드 백엔드에서 자리 잡음. |
| valibot | 2023 | 트리 셰이킹 친화. 함수 단위 가져오기. |
| ArkType | 2023 | TS 표현식을 그대로 파싱해 런타임 타입을 만듦. |
8. 자주 걸리는 자리
any 와 unknown 의 차이 — any 는 검사 우회, unknown 은 "정체를 모름". catch 변수가 any 였던 옛 동작은 useUnknownInCatchVariables 로 unknown 이 됨. 좁히지 않으면 사용할 수 없게 만들어 안전.
as 단언의 남용 — 단언은 검사를 끄는 도구. 검증 함수 (parse) 로 바꿀 수 있는 자리에 as 가 자라기 쉬움.
enum 의 함정 — TS 의 enum 은 런타임 객체를 만들고 트리 셰이킹이 어려움. 자주 권장되는 대안은 as const 객체 + 유니온 타입 추출.
타입과 런타임의 분리 — 타입은 빌드 시 사라짐. 런타임 분기는 zod 같은 검증 또는 typeof · in 으로 직접 만들어야.
타입 정의 패키지 — JS 라이브러리는 타입이 없을 수 있음. @types/<pkg> (DefinitelyTyped) 가 별도 패키지.
하고픈 말
TypeScript strict + zod 의 결합이 컴파일 타임 + 런타임 두 자리를 모두 잡는 표준 짝. any 와 as 의 사용을 의도적으로 적게 두면 타입 시스템의 가치가 거의 그대로. 외부에서 들어오는 모든 데이터는 zod parse 한 번을 거치는 습관이 운영의 안정성을 크게.
Next
- java21-modern
- python-async
TypeScript 공식 사이트 · TypeScript GitHub · TSConfig Reference · Strict Mode Family 문서 · DefinitelyTyped · TC39 ECMAScript proposals · zod · valibot · ArkType 을 참고합니다.