3.0 타입의 모든 것
- 타입: 값과 이 값으로 할 수 있는 일의 집합
- type checker를 이용하여 유효하지 않은 동작이 실행되는 일 예방
- TS 타입 계층
- Unknown
- Any, (Void - Undefined, Null)
- Number
- Number Enum
- BigInt
- Boolean
- String
- String Enum
- Symbol
- Unique Symbol
- Object
- Array
- Tuple
- Function
- Constructor
- Never
3.1 타입을 이야기하다
- TS는 특정 타입만 와야 할 때 이를 명시할 수 있는 언어
3.2 타입의 가나다
- any
- 꼭 필요한 상황이 아니면 사용하지 않는 것이 좋음 (반드시 최후의 수단으로 사용하기)
- any는 모든 값의 집합이므로 모든 것을 할 수 있음
- any 사용 위해 명시적으로 선언해야 함
- TSC 플래그: noImplicitAny
- 암묵적인 any가 나타났을 때 예외 발생시키고 싶으면 tsconfig.json에서 noImplicitAny 플래그 활성화
- unknown
- 타입을 미리 알 수 없는 어떤 값이 있을 때 any 대신 unknown 사용
- any처럼 모든 값을 대표하지만, unknown의 타입을 검사해 refine하기 전까지는
TS가 unknown 타입의 값을 사용할 수 없게 강제함
- 비교 연산, 반전(!) 연산 지원
- JS의 typeof, instanceof 연산자로 정제 가능
- unknown 타입을 사용하고자 한다면 개발자가 명시적으로 설정해야 함
- unknown 타입이 아닌 값과 unknown 타입의 값 비교 가능
- 유니온 타입에 unknown 포함되어 있으면 결과는 unknown
- boolean
- true/false
- 비교 연산과 반전(!) 연산 가능
- 타입 리터럴: 오직 하나의 값을 나타내는 타입 (값을 타입으로 사용 가능)
- 모든 곳에서 일어날 수 있는 실수를 방지해 안전성을 추가로 확보해주는 강력한 언어 기능
- const를 사용하면 TS가 가장 좁은 타입으로 추론함 (특정 값으로 제한, 객체와 배열은 예외)
- number
- 모든 숫자의 집합
- 숫자 관련 연산 수행 가능
- 숫자 분리자; _ (타입과 값 모두에 사용 가능)
- 대개 TS가 number 타입 추론하도록 만듦, 가끔 특정 값으로 제한해서 처리 가능, 명시적은 거의 없음
- bigint
- 라운딩 관련 에러 걱정 없이 큰 정수 처리 가능
- 모든 BigInt의 집합으로 숫자 연산 등 지원
- bigint 리터럴은 반드시 정수
- TS가 bigint 타입 추론하도록 두는 것이 좋음
- string
- 모든 문자열의 집합
- 연결(+), 슬라이스(.slice) 등의 연산 수행 가능
- TS가 string 타입 추론하도록 두는 것이 좋음
- symbol
- 객체와 맵에서 문자열 키 대신하는 용도로 사용
- 키 잘못 설정하는 실수 방지
- symbol 타입으로 추론되거나 명시적으로 unique symbol 정의 가능
- unique symbol 타입은 반드시 const
- unique symbol은 자신과 항상 같음
- unique symbol도 특정 symbol을 나타내는 타입임
- 객체
- 객체의 shape 정의
- 객체 리터럴 타입과 객체 인스턴스로 만든 타입 구분 불가 (JS가 구조 기반 타입으로 설계됨/duck typing)
- object는 서술하는 값에 관한 정보를 거의 알려주지 않고, 값 자체가 JS 객체라고 말해줄 뿐임
- 객체를 const로 선언해도 TS는 더 좁은 타입으로 추론하지 않음
- definite assignment (확실한 할당)
- 변수를 선언하고 나중에 초기화하는 상황에서 TS는 변수를 사용하기 전에 값을 할당하도록 강제함
- 기본적으로 타입스크립트는 객체 프로퍼티에 엄격한 편임
- 인덱스 시그니쳐
- TS에 어떤 객체가 여러 키를 가질 수 있음을 알려줌
- 명시적으로 정의한 키 외에 다양한 키를 객체에 안전하게 추가 가능
- 인덱스 시그니쳐의 키는 반드시 number 나 string 타입에 할당할 수 있는 타입이어야 함
- 선택형(?), readonly 한정자를 이용해 특정 필드를 읽기 전용으로 정의 가능
- 휴식 시간: 타입 별칭, 유니온, 인터섹션
- 타입 별칭
- 타입 별칭으로 타입 가리킬 수 있음
- 하나의 타입을 두 번 정의할 수는 없음
- 블록 영역에 적용됨
- 복잡한 타입을 DRY하지 않도록 해주며 변수가 어떤 목적으로 사용되었는지 쉽게 이해 가능
- 유니온과 인터섹션
- 집합처럼 연산 수행 가능
- heterogeneous 배열에도 많이 등장 (여러 타입 들어있는 배열)
- 배열
- concatenation, pushing, searching, slicing 등 지원하는 특별한 객체
- 보통 homogeneous 배열로 많이 사용 (같은 타입 들어있는 배열)
- 빈 배열로 초기화하면 any타입의 배열로 추측
- 튜플
- 튜플은 배열의 서브 타입
- 길이 고정, 각 인덱스의 타입이 알려진 배열의 일종
- 튜플 선언 시 타입 명시 필요
- 선택형 요소 지원
- 읽기 전용 배열과 튜플
- readonly 배열은 명시적 타입 어노테이션으로 만들 수 있음
- null, undefined, void, never
- undefined (아직 정의 X), null (값이 없음)
- void: 명시적으로 아무것도 반환하지 않는 함수의 반환 타입을 가리킴
- never: 절대 반환하지 않는 함수 타입 가리킴 (예외를 던지거나 영원히 실행되는)
- Unknown은 모든 타입의 상위 타입, never는 모든 타입의 서브 타입
- 열거형
- 해당 타입으로 사용할 수 있는 값을 열거하는 기법
- 문자열에서 문자열로 매핑, 문자열에서 숫자로 매핑
- const enum은 더 안전한 접근 허용
- 역방향 찾기 지원 X
- 채워 넣기 기능이 문제 발생 가능
- 사용 권장 X
- 숫자 값을 받는 열거형은 전체 열거형의 안전성을 해칠 수 있음
3.3 마치며
- TS는 다양한 내장 타입 제공
- let, var는 일반적인 타입으로 추론, const는 더 구체적인 타입으로 추론
- 구체적 타입은 보통 일반 타입의 서브 타입임
연습문제
let a = 1042; // number
let b = 'apples and oranges'; // string
const c = 'pineapples'; // "pineapples"
let d = [true, true, false]; // boolean[]
let e = { type: 'ficus' }; // { type: string }
let f = [1, false]; // (number | boolean)[]
const g = [3]; // number[]
let h = null; // any
let i: 3 = 3;
i = 4; // '4' 타입은 '3' 타입에 할당 불가
let j = [1, 2, 3];
j.push(4);
j.push('5'); // '"5"' 타입의 인수를 'number' 타입의 매개변수에 할당 불가
let k: never = 4; // '4' 타입은 'never' 타입에 할당 불가
let l: unknown = 4;
let m = l * 2; // 'unknown' 타입의 객체임
'Books > TS 프로그래밍 ✔️' 카테고리의 다른 글
[타입스크립트 프로그래밍] 2장 - 타입스크립트: 3,000미터 상공에서 내려다보기 (0) | 2022.02.03 |
---|---|
[타입스크립트 프로그래밍] 1장 - 소개 (0) | 2021.12.23 |
댓글