TypeScript를 제대로 활용하기 위해서는 tsconfig.json의 컴파일러 옵션을 이해하는 것이 필수입니다. 특히 strict 모드와 관련된 옵션들은 코드 안정성, 개발 경험, 유지보수성을 크게 좌우합니다.
strict 옵션 — 모든 타입 검사 강화
strict는 컴파일러의 가장 강력한 옵션으로, 여러 엄격 모드 옵션을 한 번에 켭니다.
{
"compilerOptions": {
"strict": true
}
}
strict = true일 때 활성화되는 주요 옵션:
noImplicitAnystrictNullChecksstrictBindCallApplystrictFunctionTypesstrictPropertyInitializationalwaysStrictuseUnknownInCatchVariables
Strict 모드를 사용하면 타입 안정성이 극적으로 높아지기 때문에 모든 실무 프로젝트에서 strict 사용을 강력히 권장합니다.
noImplicitAny — 암묵적인 any 금지
TypeScript에서 타입을 명시하지 않으면 자동으로 any가 되지만, 이는 타입 시스템의 장점을 무력화합니다. 이를 막는 옵션이 noImplicitAny입니다.
// noImplicitAny: true
function sum(a, b) { // 오류: 'a', 'b'가 any로 추론
return a + b;
}
자동으로 any가 되는 것을 막아 타입 명시를 강제하기 때문에 코드의 안전성이 크게 높아집니다.
strictNullChecks — null/undefined 안전성 확보
null과 undefined를 타입 시스템에서 엄격하게 다루도록 하는 옵션입니다.
let name: string = null;
// strictNullChecks: true → 오류
이 옵션은 null 관련 런타임 오류를 대폭 줄이며, 현대 TypeScript 프로젝트에서는 사실상 필수입니다.
strictPropertyInitialization — 클래스 필드 초기화 검사
클래스의 필드가 생성자에서 반드시 초기화되었는지 검사합니다.
class User {
name: string; // strictPropertyInitialization 오류
constructor() {}
}
해결 방법은 두 가지입니다:
class User {
name: string;
constructor(name: string) {
this.name = name; // ✔ OK
}
}
혹은 “! 단언 연산자” 사용:
class User {
name!: string; // ✔ 개발자가 책임지고 초기화한다고 선언
}
strictFunctionTypes — 함수 타입 검사 강화
함수의 매개변수 타입을 더 엄격하게 검사하여 안전하지 않은 함수 대입을 막아주는 옵션입니다.
type Fn = (value: string) => void;
let f: Fn;
let g = (value: string | number) => {};
// strictFunctionTypes → 대입 불가
콜백 기반 로직, 이벤트 핸들러 등에서 타입 안정성을 강화합니다.
strictBindCallApply — call/apply/bind 타입 검사 강화
자바스크립트의 call/apply/bind는 인자를 유연하게 받기 때문에 잘못된 인자가 전달돼도 오류가 발생하지 않는 문제가 있습니다.
function greet(name: string) {
return `Hello ${name}`;
}
greet.call(null, 123); // strictBindCallApply: true → 오류
함수 인자 타입이 제대로 검사되기 때문에 안정적인 코드를 작성할 수 있습니다.
alwaysStrict — 항상 "use strict" 적용
컴파일된 JavaScript 파일에 항상 "use strict" 모드를 적용합니다.
{
"compilerOptions": {
"alwaysStrict": true
}
}
use strict는 JavaScript의 다양한 안전 장치를 활성화하므로 TypeScript 프로젝트에서는 일반적으로 켜 두는 것을 권장합니다.
noImplicitThis — this 암시적 any 금지
this가 암시적으로 any로 되는 상황을 막는 옵션입니다.
function hello() {
console.log(this.name); // this: any → 오류
}
특히 객체 메서드를 분리해서 호출할 때 발생하는 오류를 예방합니다.
noImplicitReturns — 반환값 누락 검사
함수에서 모든 코드 경로가 값을 반환해야 한다는 규칙을 검사합니다.
function getValue(x: number) {
if (x > 0) return x;
// noImplicitReturns 오류: 경로 중 return 없음
}
분기 처리에서 실수로 return을 빠뜨리는 오류를 막아줍니다.
useUnknownInCatchVariables — catch 변수의 기본 타입을 unknown으로
기존 catch 변수 타입은 any였습니다. 이 옵션이 true이면 자동으로 unknown이 되어 타입 안전성이 높아집니다.
try {
throw new Error("fail");
} catch (e) {
e.message; // unknown → Error 타입으로 narrowing 필요
}
예외 처리에서 타입 가드를 적용하도록 유도해 더 안전한 코드를 만들 수 있습니다.
실무에서 추천되는 tsconfig 설정
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"useUnknownInCatchVariables": true
}
}
위 설정은 대부분의 프로젝트에서 안정성과 생산성을 모두 만족시키는 구성입니다.
TypeScript의 컴파일러 옵션은 코드 품질과 안정성에 직접적인 영향을 미칩니다. 특히 strict 모드와 null/any 관련 옵션들은 실무에서 반드시 켜야 하며, 이를 통해 타입 시스템을 제대로 활용할 수 있습니다.
- strict는 TypeScript의 핵심 안전 기능
- noImplicitAny, strictNullChecks는 사실상 필수
- strictFunctionTypes, strictBindCallApply는 함수 안정성 강화
- noImplicitReturns, noImplicitThis는 유지보수성 증대
'개발 > Typescript' 카테고리의 다른 글
| [TYPESCRIPT] 제네릭 함수와 클래스 활용하기 - 재사용성과 타입 안정성을 모두 잡는 방법 (0) | 2025.12.09 |
|---|---|
| [TYPESCRIPT] 제네릭(Generic) 기초 이해하기 - 타입을 입력받는 유연한 타입 설계 (0) | 2025.12.08 |
| [TYPESCRIPT] 타입 확장과 중복 방지 패턴 - 유지보수성을 극대화하는 TypeScript 실무 전략 (0) | 2025.12.06 |
| [TYPESCRIPT] keyof와 typeof 활용하기 - 객체 기반 타입 설계를 정교하게 만드는 핵심 문법 (0) | 2025.12.05 |
| [TYPESCRIPT] 타입 단언(Type Assertion)과 타입 가드(Type Guard) - 타입 안정성을 지키는 핵심 도구 (0) | 2025.12.04 |
