never를 사용한 완전성 검사
never로 처리되지 않은 경우를 컴파일 시점에 포착합니다.
never를 사용한 완전성 검사은(는) CoddyKit의 무료 TypeScript Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 TypeScript Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. TypeScript Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
모든 경우를 처리해야 하는 문제
새 유니온 멤버를 추가하면 어딘가에서 해당 멤버를 처리하는 것을 잊기 쉽습니다. 완전성 검사를 사용하면 이런 누락이 컴파일 오류로 나타납니다.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
// If we add "triangle" later, we want every switch to complain.never 타입
never 타입은 절대 발생할 수 없는 값을 나타냅니다. 모든 경우를 처리하면 기본 분기에 도달하는 값의 타입은 never가 됩니다.
function fail(): never {
throw new Error("unreachable");
}
// never is assignable to nothing except never itself.기본 case에서 never에 할당하기
default 분기에서 값을 never 변수에 할당합니다. 모든 변형을 처리하면 할당이 컴파일되고, 그렇지 않으면 오류가 발생합니다.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
default:
const _exhaustive: never = s;
return _exhaustive;
}
}
console.log(area({ kind: "square", side: 3 }));case를 잊으면 어떻게 될까요
triangle 멤버를 추가하고 해당 case를 잊으면 default의 s는 더 이상 never가 아니므로 컴파일 시 할당에 실패합니다.
// type Shape = ... | { kind: "triangle"; base: number; height: number };
// Now in default, s is { kind: "triangle"; ... }
// const _exhaustive: never = s; // Error: triangle not assignable to neverassertNever 도우미
재사용 가능한 assertNever 함수로 이 패턴을 한곳에 모을 수 있습니다. 이 함수는 never를 받고 예외를 발생시키며, 해당 분기에 도달할 수 없어야 한다는 점을 명확히 보여 줍니다.
function assertNever(value: never): never {
throw new Error("Unhandled case: " + JSON.stringify(value));
}
console.log(typeof assertNever);switch에서 assertNever 사용하기
default case에서 assertNever(s)를 호출합니다. 컴파일 시 모든 경우를 처리하도록 강제하고, 실제로 해당 분기에 도달하면 명확한 런타임 오류를 발생시킵니다.
function assertNever(value: never): never {
throw new Error("Unhandled: " + JSON.stringify(value));
}
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
default: return assertNever(s);
}
}
console.log(area({ kind: "circle", radius: 1 }).toFixed(2));컴파일 시 안전성과 런타임 안전성
never 검사는 코드를 실행하기 전에 누락된 경우를 찾아내며, 발생한 오류는 타입 검사를 통과한 문제가 런타임에 나타날 때 보호 장치가 됩니다.
function assertNever(x: never): never {
throw new Error("Unhandled: " + String(x));
}
// Compile error if a case is missing; runtime throw as a backstop.
console.log("two layers of safety");default 없이 완전성 검사하기
함수에 명시적인 반환 타입이 있고 switch가 모든 경우를 포함하면 TypeScript는 반환 누락도 알려 줄 수 있습니다. 이것 역시 완전성 검사의 한 형태입니다.
type Light = "red" | "yellow" | "green";
function next(l: Light): Light {
switch (l) {
case "red": return "green";
case "yellow": return "red";
case "green": return "yellow";
}
// No default needed; all cases return.
}
console.log(next("red"));if/else 연결에서 완전성 검사하기
같은 방식은 if/else에도 적용됩니다. 각 변형을 처리하고 나면 마지막 else는 never 값을 받습니다.
function assertNever(x: never): never { throw new Error("bad"); }
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function name(s: Shape): string {
if (s.kind === "circle") return "circle";
else if (s.kind === "square") return "square";
else return assertNever(s);
}
console.log(name({ kind: "square", side: 2 }));never가 적합한 도구인 이유
never는 어떤 것에도 할당될 수 없으므로 남아 있는 변형이 있으면 할당이 실패합니다. 따라서 처리되지 않은 경우를 찾아내는 데 never가 가장 적합합니다.
// Only never is assignable to never.
let x: never;
// x = "hi"; // Error
// Any concrete leftover type fails the same way.
console.log("never catches gaps");리팩터링의 안전망으로 사용하는 완전성 검사
모든 곳에서 assertNever를 사용하면 유니온 멤버를 추가했을 때 업데이트해야 하는 모든 위치를 정확히 가리키는 정리된 컴파일 오류 목록이 만들어집니다.
function assertNever(x: never): never { throw new Error("unhandled"); }
type Status = "idle" | "busy";
function render(s: Status): string {
switch (s) {
case "idle": return "Idle";
case "busy": return "Busy";
default: return assertNever(s);
}
}
console.log(render("idle"));빠른 확인: 완전성 검사
완전성 검사에 대한 이해도를 확인해 보세요.
복습: never를 사용한 완전성 검사
기본값을 never에 할당하거나 assertNever에 전달하면 컴파일러가 모든 변형을 처리하도록 강제한다는 것을 배웠습니다. 이를 통해 잊어버린 경우가 컴파일 오류로 나타납니다.
function assertNever(x: never): never { throw new Error("unhandled"); }
type Shape = { kind: "circle"; radius: number } | { kind: "square"; side: number };
function f(s: Shape) {
switch (s.kind) {
case "circle": return s.radius;
case "square": return s.side;
default: return assertNever(s);
}
}
console.log(f({ kind: "circle", radius: 5 }));자주 묻는 질문
“never를 사용한 완전성 검사” 강의는 무료인가요?
네 — “never를 사용한 완전성 검사” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 TypeScript Academy 강의 전체를 잠금 해제할 수 있습니다. TypeScript Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“never를 사용한 완전성 검사”에서 뭘 배우나요?
never로 처리되지 않은 경우를 컴파일 시점에 포착합니다. 브라우저에서 직접 실행하는 실습 코드로 TypeScript Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
TypeScript Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 TypeScript Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“never를 사용한 완전성 검사” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 TypeScript Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 TypeScript Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 판별 유니언 구축
- 판별 속성에 따른 타입 좁히기
- never를 사용한 완전성 검사
- 상태 머신 모델링