tsconfig.json의 "strict": true는 noImplicitAny와 strictNullChecks를 비롯한 핵심 엄격 검사들을 한꺼번에 켜는 묶음 스위치입니다. 여기에 noUncheckedIndexedAccess 옵션을 추가로 켜면 배열이나 인덱스 시그니처에서 값을 꺼낼 때의 undefined 가능성(TS18048)까지 검사 단계에서 미리 잡아낼 수 있습니다.
같은 코드를 놓고 옵션을 껐을 때, 기본 strict만 켰을 때, 그리고 noUncheckedIndexedAccess까지 켰을 때 검사 결과가 어떻게 달라지는지 비교해 보고, 옵션을 어떻게 바꾸든 실행 결과는 늘 같다는 원리(검사 규칙 1)를 확인합니다.
1"strict": true가 켜는 두 기둥
"strict": true 한 줄은 여러 세부 검사 옵션을 동시에 켭니다. 그중 우리가 매일 만나는 가장 중요한 두 기둥은 **noImplicitAny**와 **strictNullChecks**입니다.
noImplicitAny: 매개변수에 타입을 적지 않아 검사기가 몰래any로 추론해야 하는 자리(function double(n))를TS7006으로 막습니다.strictNullChecks:null과undefined를 일반 타입(string,number)에서 분리해,let memo: string = null;같은 대입을TS2322로 막습니다.
아래 코드를 과목 기본 설정("strict": true)으로 검사하고 실행해 봅니다.
function double(n) {
return n * 2;
}
let memo: string = null;
console.log(double(3), memo);
main.ts(1,17): error TS7006: Parameter 'n' implicitly has an 'any' type.main.ts(5,5): error TS2322: Type 'null' is not assignable to type 'string'.6 null만약 "strict": false로 끄면 위 두 오류가 모두 사라져 검사 오류 0이 됩니다. 하지만 실행 결과는 옵션을 켜든 끄든 똑같이 6 null입니다.
2noUncheckedIndexedAccess가 더하는 검사 (TS18048)
과목 기본 설정("strict": true)만으로는 배열이나 인덱스 시그니처에서 꺼낸 값에 undefined를 붙이지 않습니다(2단원 배열 · 3단원 인덱스 시그니처). 그래서 두 칸짜리 배열에서 items[2]를 꺼내 .length를 읽어도 타입 검사는 통과하고 실행 때 TypeError로 멈춥니다.
const items = ["커피", "라테"];
const third = items[2];
console.log(third.length);
main.ts:3console.log(third.length); ^ TypeError: Cannot read properties of undefined (reading 'length') at main.ts:3:19이 빈틈까지 검사기가 잡게 하려면 tsconfig.json에 noUncheckedIndexedAccess 옵션을 true로 더합니다.
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true
}
}
이 옵션을 켜면 items[2]의 지금 타입이 string이 아니라 **string | undefined**가 됩니다. 따라서 undefined를 거르지 않고 third.length를 읽으면 3번 줄에서 undefined일 수 있다는 TS18048 오류가 나며, 아래와 같이 if나 ??로 거르면 안전하게 통과합니다.
const items = ["커피", "라테"];
const third = items[2];
if (third !== undefined) {
console.log(third.length);
} else {
console.log("없음");
}
없음| 코드 조각 | "strict": false | "strict": true (과목 기본) | + "noUncheckedIndexedAccess" |
|---|---|---|---|
function double(n) | 오류 없음 (n: any) | TS7006 오류 | TS7006 오류 |
let memo: string = null | 오류 없음 | TS2322 오류 | TS2322 오류 |
items[2].length | 오류 없음 (string) | 오류 없음 (string) | TS18048 오류 (string | undefined) |
| Node 실행 결과 | 모두 같음 | 모두 같음 | 모두 같음 |
예제
실행 결과를 먼저 적어 본 뒤 펼쳐 보세요. 맞혀 보기는 점수에 들지 않습니다.
매개변수 타입, null 허용 유니언, 그리고 배열 원소 ?? 기본값을 모두 갖춘 코드입니다.
function double(
n: number,
): number {
return n * 2;
}
let memo: string | null = null;
const items = ["커피", "라테"];
const third = items[2] ?? "기본";
console.log(
double(3),
memo,
third.length,
);
무엇이 찍힐까요?
실행 결과 보기
6 null 2n: number로 noImplicitAny를, string | null로 strictNullChecks를 통과하고, items[2] ?? "기본"으로 undefined를 걸러 noUncheckedIndexedAccess까지 모두 만족합니다.
자주 틀리는 곳
틀린 생각: tsconfig.json의 엄격 옵션을 바꾸면 Node 실행 결과도 달라진다.
strict나 noUncheckedIndexedAccess는 오직 검사기(tsc)가 어디에 빨간 줄을 그을지만 바꿉니다(타입이 실행 때 남는다는 생각).
맞는 규칙: Node는 실행할 때 tsconfig.json의 검사 규칙을 보지 않고 타입만 지운 뒤 실행하므로, 옵션을 켜든 끄든 실행 결과는 완전히 똑같습니다(검사 규칙 1).
틀린 생각: 빨간 줄이 많이 나오면 "strict": false로 꺼서 해결하면 된다.
"strict": false로 바꾸면 당장 터미널의 TS7006이나 TS2322 메시지는 사라집니다. 하지만 그것은 화재경보기를 끈 것과 같아서, null 참조나 잘못된 인자가 들어왔을 때 실행 중에 터지는 버그는 고스란히 남습니다.
맞는 규칙: "strict": true는 항상 켜 두고, 오류가 가리키는 자리에 타입을 적거나 조건문으로 좁혀서 해결합니다.
틀린 생각: noUncheckedIndexedAccess를 켜도 첫 번째 칸(items[0])은 무조건 값이 있다고 인정된다.
빈 배열([])이 들어올 수도 있기 때문에 검사기는 인덱스 숫자가 0이어도 똑같이 | undefined를 붙입니다.
맞는 규칙: noUncheckedIndexedAccess를 켰다면 items[0]을 읽을 때도 if (first !== undefined)나 ??로 확인해야 합니다.
확인 문제
1. "strict": true가 켜는 옵션 가운데, 매개변수 타입을 적지 않은 function add(a, b)를 TS7006으로 막아 주는 세부 옵션 이름은 무엇인가요?
힌트
1절에서 배운 두 기둥 가운데 암묵적 any를 막는 옵션 이름을 떠올려 보세요.
정답
noImplicitAny입니다. 타입을 적지 않아 암묵적으로 any가 되는 자리를 막아 줍니다.
2. 과목 기본 설정("strict": true)에 어떤 옵션을 더 켜야 const third = items[2];의 타입이 string | undefined가 되나요?
힌트
2절에서 배운 인덱스 접근 검사 옵션 이름입니다.
정답
noUncheckedIndexedAccess입니다. 이 옵션을 true로 켜면 인덱스로 꺼낸 값을 확인 없이 쓸 때 TS18048로 알려 줍니다.
3. "strict": true를 "strict": false로 바꾸면 node main.ts의 실행 결과가 달라질까요?
힌트
2절 끝의 비교 표 마지막 줄을 살펴보세요.
정답
달라지지 않습니다. strict 옵션은 타입 검사기(tsc)의 검사 기준만 바꿀 뿐, 타입을 지우고 실행하는 Node의 결과에는 영향을 주지 않습니다(타입이 실행 때 남는다는 생각).
컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요.
2절의 items[2] 코드를 main.ts에 넣고 tsconfig.json에 noUncheckedIndexedAccess 옵션을 true로 추가해 npx tsc가 TS18048을 잡는지 확인해 보세요. 확인이 끝나면 noUncheckedIndexedAccess 줄은 다시 지워 과목 기본 설정으로 되돌려 둡니다. 다음은 단원 연습 문제와 단원 1~10 섞어 풀기입니다.
검사하고 돌리는 법은 내 컴퓨터에서 검사하고 돌리기에 있습니다.