예외 던지기 문제가 발생하면 null 반환 대신 예외를 던지겠습니다. 그러면 어떤 문제냐에 따라 대처가 가능할 수 있고, 디버깅에 도움 되는 메타 데이터도 얻을 수 있습니다. function ask() { return prompt("생일 언제임?"); } function parse(birthday: string): Date { let date = new Date(birthday); if (!isValid(date)) { throw new RangeError('YYYY/MM/DD 로 입력하셈여') } return date; } 이제 이 코드를 사용할 때 전체 응용 프로그램이 크래시 되지 않도록 매끄럽게 처리하기 위해 주의해서 예외를 잡아야 합니다. function ask() { return prompt("..
null 반환 유저의 생일을 입력받아 Date 객체로 파싱 하는 프로그램을 구현해 봅시다. function ask(){ return prompt('생일 언제임?') } function parse(birthday: string): Date { return new Date(birthday) } let date = parse(ask()) console.info('생일은', date.toISOString()) 단순한 텍스트 입력창을 사용했으므로 사용자가 입력한 내용을 검증해야 합니다. function ask(){ return prompt('생일 언제임?') } function parse(birthday: string): Date | null{ let date = new Date(birthday) if(!isVa..
프로토타입 안전하게 확장하기 예전엔 프로토타입 확장이 안전하지 않은 일이었지만 이제 TypeScript처럼 정적 타입 시스템을 이용하면 안전하게 확장할 수 있습니다. 예시를 위해 Array 프로토타입에 zip 메서드를 추가해 보겠습니다. 프로토타입을 안전하게 확장하기 위해 두 단계로 진행할 것입니다. 먼저 .ts 파일에서 Array의 프로토타입을 확장한 다음 새로운 zip 메서드를 프로토타입에 추가합니다. // TS에 zip이 무엇인지 설명 interface Array{ // ① zip(list: U[]): [T, U][] } // .zip 구현 Array.prototype.zip = function ( this: T[], // ② list: U[] ): [T, U][] { return this.map(..
이름 기반 타입 흉내내기 예를 들어 몇 가지의 ID 타입이 있는데, 그 각각은 시스템에서 사용하는 서로 다른 종류의 객체를 고유한 방식으로 식별해 준다고 해봅시다. type CompanyID = string type OrderID = string type MemberID = string type ID = CompanyID | OrderID | MemberID MemberID 타입의 값이 "i4want4go4home" 같은 단순 해시값이라고 해봅시다. 따라서 비록 MemberID라는 별칭으로 사용했지만 실질적으론 일반 string입니다. MemberID를 인수로 받는 함수는 다음처럼 정의할 수 있습니다. type CompanyID = string type OrderID = string type Member..
확실한 할당 어서션 TypeScript는 확실한 할당 검사용으로 nonnull 어서션을 적용하는 특별한 상황에 사용할 특수 문법을 제공합니다. let userId: string userId.toUpperCase(); // 'userId' 변수가 할당되기 전에 사용되었습니다.ts(2454) 이 에러 검출은 TypeScript가 제공하는 멋진 서비스입니다. userId 변수를 선언했지만 값을 할당하는 걸 깜빡 잊은 채 대문자 변환 작업을 수행했습니다. TypeScript가 검출해주지 않았다면 런타임 에러가 발생했을 것입니다. 하지만 코드가 다음과 같다면 어떨까요? let userId: string fetchUser() userId.toUpperCase(); // 'userId' 변수가 할당되기 전에 사용되었..
Nonnull 어서션 null이 될 수 있는 특별한 상황(T | null 또는 T | null | undefined 타입)을 대비해 TypeScript는 어떤 값의 타입이 null이나 undefined가 아니라 T임을 단언하는 특수 문법을 제공합니다. 몇 가지 상황에서 이 기능을 활용할 수 있습니다. 예를 들어 웹 앱에서 다이얼로그를 보여주거나 숨기는 프레임워크를 개발했다고 가정합니다. 각 다이얼로그는 고유의 ID를 가지며 이 ID로 다이얼로그의 DOM 노드 참조를 얻을 수 있습니다. DOM 노드에서 다이얼로그가 사라지면 ID를 삭제해서 DOM 안에 다이얼로그가 더 이상 존재하지 않음을 알립니다. type Dialog = { id?: string } function closeDialog(dialog: D..
탈출구 상황에 따라서는 타입을 완벽하게 지정하지 않고도 어떤 작업이 안전하다는 사실을 TypeScript가 믿도록 만들고 싶을 때가 있습니다. 예를 들어 사용하고 있는 서드 파티 모듈의 타입 정의가 잘못되었음을 파악한 후, DefinitelyTyped에 수정 사항을 기여하기 앞서 코드에서 먼저 검증해보려 한다거나, 아폴로(Apollo)로 타입 선언을 다시 만들지 않은 채 API가 반환한 데이터를 사용해야 하는 상황일 수도 있습니다. 다행히 TypeScript는 안전한 작업임을 증명할 시간이 없을 때 활용할 수 있는 탈출구를 제공합니다. 명확하지 않다면, 다음에 나열하는 TypeScript 기능들은 되도록 적게 사용하는 게 좋습니다. 이 기능들에 너무 의존하는 상황이라면 무언가 잘못된 것일 수 있습니다. ..
내장 조건부 타입들 조건부 타입을 이용하면 정말 강력한 연산자 몇 가지를 타입 수준에서 표현할 수 있습니다. TypeScript가 전역에서 바로 사용할 수 있는 여러 조건부 타입을 제공하는 이유도 바로 이 때문입니다. Exclude Without 타입처럼 T에 속하지만 U에는 없는 타입을 구합니다. type A = number | string type B = string type C = Exclude // type C = number Extract T의 타입 중 U에 할당할 수 있는 타입을 구합니다. type A = number | string type B = string type C = Extract // type C = string NonNullable T에서 null과 undefined를 제외한 버..
infer 키워드 조건부 타입의 마지막 특성으로 조건의 일부를 제네릭 타입으로 선언할 수 있는 기능을 꼽을 수 있습니다. 참고로 지금까진 제네릭 타입 매개변수를 선언하는 방법으로 꺾쇠괄호()를 이용하는 방법 한 가지만 배웠습니다. 조건부 타입에선 제네릭 타입을 인라인으로 선언하는 전용 문법을 제공합니다. 바로 infer 키워드입니다. 배열의 요소 타입을 얻는 ElementType이라는 조건부 타입을 정의해 봅시다. type ElementType = T extends unknown[] ? T[number] : T type A = ElementType // type A = number infer를 이용하면 이 코드를 다음처럼 다시 구현할 수 있습니다. type ElementType2 = T extends (..