타입스크립트 never 타입 예제
타입스크립트에는 never 키워드를 볼 수 있다.
never 타입은 void와 비슷하게 반환값이 없다는 의미도 있지만, 실제로 값이 없거나, 코드가 정상적으로 동작하지 않는 상황을 표현하는 타입이다.
문장으로는 의미가 와닿지 않는다.
쉽게 생각해서 발생할 수 없는 모든 상황, 절대로 값이 존재하지 않는 상태로 우선 외우고 넘어가자.
let result: never;
result = "hello";
// 오류: Type 'string' is not assignable to type 'never'.
result = 10;
// 오류: Type 'number' is not assignable to type 'never'.-
function throwError(message: string): never {
throw new Error(message);
}-
function getUserName(name?: string): string {
if (!name) {
throwError("사용자 이름이 없습니다.");
}
return name.toUpperCase();
}-
function runForever(): never {
while (true) {
console.log("실행 중");
}
}-
function formatValue(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
if (typeof value === "number") {
return value.toFixed(2);
}
const unreachable: never = value;
return unreachable;
}-
type PaymentStatus =
| { type: "ready"; amount: number }
| { type: "paid"; receiptId: string }
| { type: "failed"; reason: string };-
function getPaymentMessage(status: PaymentStatus): string {
switch (status.type) {
case "ready":
return `결제 예정 금액은 ${status.amount}원입니다.`;
case "paid":
return `결제가 완료되었습니다. 영수증: ${status.receiptId}`;
case "failed":
return `결제에 실패했습니다. 사유: ${status.reason}`;
default: {
const exhaustiveCheck: never = status;
return exhaustiveCheck;
}
}
}-
type PaymentStatus =
| { type: "ready"; amount: number }
| { type: "paid"; receiptId: string }
| { type: "failed"; reason: string }
| { type: "cancelled"; cancelledAt: Date };-
const exhaustiveCheck: never = status;-
function assertNever(value: never): never {
throw new Error(
`처리하지 않은 값입니다: ${JSON.stringify(value)}`
);
}-
function getPaymentMessage(status: PaymentStatus): string {
switch (status.type) {
case "ready":
return `결제 예정 금액은 ${status.amount}원입니다.`;
case "paid":
return `결제가 완료되었습니다. 영수증: ${status.receiptId}`;
case "failed":
return `결제에 실패했습니다. 사유: ${status.reason}`;
default:
return assertNever(status);
}
}-
type OnlyString<T> = T extends string ? T : never;
type Result = OnlyString<string | number | boolean>;
// 결과: string-
OnlyString<string> // string
OnlyString<number> // never
OnlyString<boolean> // never-
string | never | never-
type ExcludeNumber<T> = T extends number ? never : T;
type Value = ExcludeNumber<string | number | boolean>;
// string | boolean-
type RemoveId<T> = {
[K in keyof T as K extends "id" ? never : K]: T[K];
};
interface User {
id: number;
name: string;
email: string;
}
type UserWithoutId = RemoveId<User>;-
type UserWithoutId = {
name: string;
email: string;
};-
function printMessage(message: string): void {
console.log(message);
}-
function stopProgram(message: string): never {
throw new Error(message);
}-
???
댓글
댓글 쓰기