* 타입스크립트 프로그래밍(보리스 체르니, 프로그래밍 인사이트)를 읽고 요약 정리한 글입니다.
타입스크립트 에러 표현/처리의 일반적인 패턴 4가지
1) null 반환
2) 예외 던지기
3) 예외 반환
4) Option 타입
7.1 null 반환
- 타입 안정성을 유지하면서 에러를 처리하는 가장 간단한 방법이다.
- 입력의 유효성을 검사하여 유효하지 않은 경우 null을 반환하고, 타입 시스템에서 모든 상황이 처리되는지를 확인한다.
function ask() {
return prompt("When is your birthday?");
}
function parse(birthday: string): Date | null {
let date = new Date(birthday);
if (!isValid(date)) {
return null; // 입력이 유효하지 않으면 null을 반환한다.
}
return new Date(birthday);
}
// 입력한 날짜가 유효한지 검사하는 함수
function isValid(date: Date) {
return (
Object.prototype.toString.call(date) === "[object Date]" &&
!Number.isNaN(date.getTime())
);
}
let date = parse(ask());
// 결과가 null인지 확인 후 결과를 사용한다.
if (date) {
console.info("Date is", date.toISOString());
} else {
console.error("Error parsing date for some reason");
}
문제점
- 문제가 생긴 원인 알 수 없어서 로그 확인하면서 디버깅해야 함
- 모호한 에러메시지
- 조합이 어려워짐 (모든 연산에서 null을 확인해야 하므로 연산 중첩, 연결시 코드가 지저분해짐)
7.2 예외 던지기
문제 발생시 예외를 던지는 방법
장점
- 어떤 문제인지에 따라 대체 가능할 수 있음
- 디버깅에 도움되는 메타데이터 얻을 수 있음
- 커스템 에러 이용하여 문제를 구체적으로 알리고, 문제 원인도 설명할 수 있음 (여러 동작을 하나의 try/catch문으로 감싸서 연쇄적이고 중첩된 동작을 효율적으로 만들 수 있음)
유의할 점 및 응용
- 전체 응용프로그램이 크래시 되지 않도록 주의 필요(try-catch문 사용)
- 다른 에러 발생시 무시하지 않고 다시 던지는 것이 좋다.
// ...
function parse(birthday: string): Date | null {
let date = new Date(birthday);
if (!isValid(date)) {
throw new RangeError("Enter a date in the form YYYY/MM/DD"); // 문제 발생시 에러를 던짐
}
return new Date(birthday);
}
// ...
// 에러를 던질때 전체 응용프로그램이 크래시 되지 않도록 try-catch 사용
try {
let date = parse(ask());
console.info("Date is", date.toISOString());
} catch (e) {
if (e instanceof RangeError) {
console.error(e.message);
} else {
throw e; // 다른 에러 발생시 무시하지 않고 다시 던지도록 함
}
}
- 추후 서브클래싱을 통해 추가한 에러 구분 가능
: 커스텀 에러 이용 -> 문제 구체화 가능, 문제 생긴 이유 설명 가능
// 커스텀 에러 타입
class InvaliddateFormatError extends RangeError {}
class DateIsInTheFutureError extends RangeError {}
function parse(birthday: string): Date | null {
let date = new Date(birthday);
if (!isValid(date)) {
throw new InvaliddateFormatError("Enter a date in the form YYYY/MM/DD");
}
if (date.getTime() > Date.now()) {
throw new DateIsInTheFutureError("Are you a timelord?");
}
return new Date(birthday);
}
try {
let date = parse(ask());
console.info("Date is", date.toISOString());
} catch (e) {
if (e instanceof InvaliddateFormatError) {
console.error(e.message);
} else if (e instanceof DateIsInTheFutureError) {
console.info(e.message);
} else {
throw e;
}
}
7.3 예외 반환
- 타입스크립트는 예외를 함수의 시그니처로 취급하지 않으므로, 특정 타입의 에러를 처리하기 위한 별도의 방법이 필요하다.
- 타입스크립트는 throws문을 지원하지 않지만 유니온 타입을 이용해서 흉내낼 수 있다.
- 함수 시그니처에 발생할 수 있는 예외 나열, 메서드 사용자에게 발생 가능한 에러 전달, 메서드 사용자가 각각의 에러를 모두 처리하거나 다시 던지도록 강제하
// ...
function parse(
birthday: string
): Date | InvaliddateFormatError | DateIsInTheFutureError {
let date = new Date(birthday);
if (!isValid(date)) {
throw new InvaliddateFormatError("Enter a date in the form YYYY/MM/DD");
}
if (date.getTime() > Date.now()) {
throw new DateIsInTheFutureError("Are you a timelord?");
}
return new Date(birthday);
}
// ...
let result = parse(ask());
if (result instanceof InvaliddateFormatError) {
console.error(result.message);
} else if (result instanceof DateIsInTheFutureError) {
console.info(result.message);
} else {
console.info("Date is", result.toISOString());
}
//좀더 간단한 방법
let result = parse(ask());
if (result instanceof Error) {
console.error(result.message);
} else {
console.info("Date is", result.toISOString());
}
장점
- 단순, 자료구조 사용하지 않음
단점
- 에러를 던지는 연산을 연쇄적으로 호출할 경우, 코드가 지저분해짐
7.4 Option 타입
특수 목적 데이터 타입을 사용해 예외를 표현하는 방법
: Try, Option, Either 타입 등
- JS에서 기본 제공되지 않으므로 설치나 구현 필요
장점
- 에러 발생할 수 있는 계산에 여러 연산을 연쇄적으로 수행할 수 있음
단점
- 이런 데이터 타입을 사용하지 않는 다른 코드와 호환되지 않음
Option 타입
핵심 개념
어떤 특정 값을 반환하는 대신 컨테이너를 반환한다.
- 컨테이너
- 값을 포함할수도 있고, 포함하지 않을 수도 있다.
- 컨테이너는 자체 제공 메서드가 있으며, 이를 이용해 연쇄 연산을 수행할 수 있다.
- 값을 포함할 수 있다면, 어떤 자료구조로도 컨테이너를 구현할 수 있다.
정의
interface Option<T> {}
class Some<T> implements Option<T> {
constructor(private value: T) {}
}
class None implements Option<never> {}
1) Some<T>와 None이 구현하게 될 인터페이스 이다.
- Some<T>, None: Option의 한 형태인 클래스
- Some<T> : T라는 값을 포함하는 Option, 연산에 성공하여 값이 만들어진 상황을 나타내며 결괏값을 포함함.
- None: 값이 없는 Option, 연산에 실패한 상황을 나타냄.
2) 타입이기도 하고 함수이기도 하다.
- 타입 관점: Some과 None의 슈퍼타입
- 함수 관점: Option 타입의 새 값을 만드는 기능
장점
- 성공하거나 실패할 수 있는 동작을 연쇄적으로 수행할 때 유리함.
- 타입 안정성 제공
- 타입 시스템을 통해 연산이 실패할 수 있음을 알려줄 수 있음
- 오버로드로 기능 추가시 더 다른 언어로 표현할 수 없는 일도 할 수 있음.
- 호출 시그니처(Some, None으로만 제한)를 활용하여 코드 안전하게 만들 수 있음
단점
- 에러 발생 이유를 알려주지는 않음
- Option을 사용하지 않는 다른 코드와는 호환되지 않음
Reference
1) 타입스크립트 프로그래밍,보리스 체르니, 프로그래밍 인사이트
'TypeScript' 카테고리의 다른 글
[타입스크립트 프로그래밍] 10장 Namespaces.Modules (2) | 2023.06.09 |
---|---|
[타입스크립트 프로그래밍] 9장 프론트엔드 프레임워크와 백엔드 프레임워크 (0) | 2023.06.09 |
[타입스크립트 프로그래밍] 5장 클래스와 인터페이스 (2) | 2023.05.31 |
댓글