반응형
타입(type)이란
- 어떤 값과 이 값으로 할 수 있는 일의 집합
- 예를 들어, number 타입은 모든 숫자(값)와 숫자에 적용 가능한 모든 연산(+, -, *, /, %)과 숫자에 호출할 수 있는 모든 메서드(toFixed, toString 등)의 집합이다.
- 중요한 것은 타입스크립트가 타입 검사기를 이용해 유효하지 않은 동작이 실행되는 일을 예방한다는 것이다.
// 매개변수에 타입 지정하기
function sqaureOf(n: number) {
return n * n;
}
sqaureOf(2); // 4
sqaureOf("2"); // Argument of type 'string' is not assignable to parameter of type 'number'
- 위와 같이 타입을 제한하면 타입스크립트가 함수 호출 시에 매개변수에 number만 올 수 있도록 제한한다.
타입의 종류
1. any
- 모든 값의 집합으로 모든 것을 할 수 있는 타입
- 값이 자바스크립트처럼 동작하기 때문에 되도록 사용하지 말아야 한다.
- 드물게 함수 매개변수 타입 정의를 지정하지 않았거나 타입을 사용하지 않는 자바스크립트 모듈을 임포트하는 경우 사용할 수 있다.
let a: any = 666;
let b: any = ["danger"];
let c = a + b;
📍 noImplicitAny : 암묵적인 any가 나타났을 때 예외를 발생시키고 싶은 경우 활성화. strict family에 속하므로 tsconfig.json에서 strict를 활성화하면 자동으로 적용된다.
2. unknown
- 모든 값의 집합이지만 비교 연산(==, ===, ||, &&, ?)과 반전(!), typeof, instanceof 연산만 가능한 타입
- 타입을 미리 알 수 없는 값이 있다면 any보다 unknown를 사용하는 것이 좋다. 그 이유는 unknown은 정제하기 전까지는 이 타입의 값을 사용할 수 없도록 제한되기 때문이다.
- 모든 타입의 상위 타입. 즉, 모든 타입을 포함하므로 모든 타입을 할당할 수 있는 타입이다.
let a: unknown = 30; // unknown
let b = a === 123; // boolean
let c = a + 10; // 'a' is of type 'unknown'
if (typeof a === "number") {
let d = a + 10; // number
}
- unknown 타입을 사용하려면 항상 명시적으로 작성해야 한다. 암묵적으로 추론되는 경우는 없다.
- 타입스크립트에게 해당 값이 특정 타입임을 증명해야 해당 타입에서 지원하는 동작을 수행할 수 있다. 예를 들어 if 문 내부에서 number임을 지정해야 number 타입에서 수행 가능한 + 연산을 할 수 있게 된다.
3. boolean
- 참(true), 거짓(false) 두 개의 값을 갖고, **비교 연산(==, ===, ||, && ?)과 반전 연산(!)**이 가능한 타입
let a = true; // boolean
const c = true // true
let d: boolean = true
let b: true = true; // true
let c: true = false; // Type 'false' is not assignable to type 'true'
- 타입을 명시하지 않고 boolean 또는 특정 boolean값을 추론하게 하거나 타입을 boolean 또는 특정 boolean 값으로 명시해 한정할 수 있다. 일반적으로 타입스크립트가 추론하도록 한다.
- e, f처럼 오직 하나의 값을 나타내는 타입을 타입 리터럴이라고 한다. 타입 리터럴은 발생할 수 있는 실수를 방지해 안전성을 추가로 확보해주는 강력한 기능이다.
- c와 같이 const를 사용하면 변수 값이 변하지 않는다고 가정하고 가장 좁은 타입인 타입 리터럴로 추론한다.
4. number
- 모든 숫자(정수, 소수, 양수, 음수, Infinity,, NaN 등)의 집합이고, 숫자 관련 연산(+, 0-, %, < 등)을 수행할 있는 타입
let a = 1234; // number
const b = 5678; // 5678
let d = a < b; // boolean
let e: number = 100; // number
let f: 12.345 = 12.345; // 12.345
let g: 12.345 = 12; // Type '12' is not assignable to type '12.345'
- boolean과 마찬가지로 타입스크립트가 number 타입 또는 특정 number 값을 추론하게 하거나 number 타입 또는 특정 number 값으로 타입을 명시해 한정할 수 있다. 일반적으로 타입스크립트가 추론하도록 한다.
📍 긴 숫자를 처리할 때는 숫자 분리자를 이용해 읽기 쉽게 만들 수 있다.
let onMillion = 1_000_000 // 1000000과 같음 let twoMillion = 2_000_000 // 2000000
5. bigint
- 모든 BigInt의 집합으로 사칙연산과 비교 등의 연산이 가능한 타입
- number는 2^53까지 정수를 표현할 수 있지만 bigint는 이보다 더 큰 수를 표현할 수 있다.
- bigint도 boolean, number와 마찬가지 방법으로 선언할 수 있고, 가능하면 타입스크립트가 추론하도록 하는 것이 좋다.
6. string
- 모든 문자열의 집합으로 연결(+), 슬라이스(slice) 등의 연산이 가능한 타입
- boolean, number와 마찬가지 방법으로 선언할 수 있고, 가능하면 타입스크립트가 추론하도록 하는 것이 좋다.
7. symbol
- symbol 값 또는 특정 symbol 값(unique symbol)을 나타내는 타입. 할 수 있는 동작이 별로 없다.
- symbol 타입으로 추론되거나 명시적으로 unique symbol 타입을 정의할 수 있다. const로 정의하는 경우 타입스크립트가 unique symbol 타입으로 추론한다.
- 객체와 맵에서 문자열 키를 대신하는 용도로 사용
8. 객체
- typeof 연산자가 object로 반환하는 모든 타입.
- 객체 타입만으로는 간단한 객체와 복잡한 객체를 구분할 수 없다. 이는 자바스크립트가 구조 기반 타입을 갖도록 설계되었고, 타입스크립트도 이 방식을 선호하기 때문이다.
📍 구조 기반 타입화 ⭐⭐⭐
객체의 이름에 상관없이 객체가 어떤 프로퍼티를 갖고 있는지를 따진다. 이를 일부 언어에서는 덕 타이핑(duck typing)이라고 한다.
"오리처럼 걷고, 오리처럼 꽥꽥거리면, 그것은 틀림없이 오리다."
즉, 덕 타이핑은 오리의 정의를 내린 속성을 가진 모든 객체를 오리라고 본다는 것이다. 오리라고 정의를 내린 메서드와 속성을 포함하고 있는 모든 객체는 오리다.
타입스크립트는 어떤 타입의 값이 변수에 할당 가능한지를 확인하는데, 이를 구조적 타이핑이라고 한다. 구조적 타이핑은 객체 타입 간에 할당할 때 적용된다. (원시 타입 간 X).
객체가 할당 가능한지는 객체의 실제 유형이 아니라 특정 메서드와 속성에 의해 결정된다. 객체는 변수의 타입이 할당하는 타입을 포함하고 있는 경우에 할당 가능하다. 다시 말해, 변수의 타입이 할당하는 타입의 상위 타입인 경우 가능하다고 볼 수 있다. 예를 들어, 배열 타입은 객체 타입에 할당 가능하고, 튜플은 배열에 할당 가능하다.
객체를 선언하는 방법은 여러 가지가 있다. 그 중 객체 리터럴 또는 object 타입을 사용해야 한다.
- object로 선언 : 어떤 필드를 가지고 있는지는 알 수 없고, 그냥 객체가 필요할 때 사용. 값의 프로퍼티에 접근 불가한 문제가 있다.
let a: object = {
b: "x",
};
a.b; // Property 'b' does not exist on type 'object'
- 객체 리터럴 문법을 사용해 타입스크립트가 추론하거나 명시적으로 타입 제한
let a = {
b: "x",
}; // {b: string}
a.b; // string
let b = {
c: {
d: "f",
},
}; // {c : {d: string}}
const c: { e: number } = {
e: 13,
}; // { e: number }
- 객체는 다른 기본 타입(boolean, number, bigint, string, symbol)과 다르게 const로 선언해도 더 좁은 타입으로 추론하지 않는다. 이것은 자바스크립트 객체의 값은 바뀔 수 있고, 타입스크립트가 이를 인지하고 있기 때문이다.
- 타입에 명시된 프로퍼티가 존재하지 않거나 추가적인 프로퍼티가 있을 때 에러가 발생한다.
- let a: { b: number }; a = {}; // Property 'b' is missing in type '{}' but required in type '{ b: number; }' a = { b: 1, c: 2, // Type '{ b: number; c: number; }' is not assignable to type '{ b: number; }' };
- 빈 객체 타입으로 선언했을 때 null, undefined를 제외한 모든 타입을 할당할 수 있다. 이는 예측할 수 없으므로 가능한 피하는 것이 좋다.
- Object 타입. 빈 객체 타입과 마찬가지로 null, undefined를 제외한 모든 타입을 할당할 수 있다. 사용하지 않는 것이 좋다.
📍 확실한 할당
타입스크립트는 변수를 사용하기 전에 값을 할당하도록 강제한다.
let i: number;
let j = i * 2; // Variable 'i' is used before being assigned.
- 선택형 객체 타입 (?) : 이 프로퍼티는 선택적으로 포함될 수 있다.
- let a: { b: number; // number 타입의 프로퍼티 b를 항상 포함 c?: string; // string 타입의 프로퍼티 c를 선택적으로 포함 [key: number]: boolean; // boolean 값을 갖는 number 타입 프로퍼티 여러 개 선택적으로 포함 };
- 읽기 전용 (readonly) : 초깃값을 할당한 이후 수정할 수 없다.
- let user: { readonly firstName: string; } = { firstName: "bichon" }; user.firstName = "kimbichon"; // Cannot assign to 'firstName' because it is a read-only property.
📍 인덱스 시그니처(index signature)
(형태) : [key: T]: U**이 객체에 모든 T 타입의 키는 U 타입의 값을 갖는다
* 어떤 객체가 명시적으로 정의한 키 외에 다양한 키를 객체에 안전하게 추가하는 방법* 인덱스 시그니처의 키(T)는 반드시 number 또는 string 타입여야 한다
let airplaneSeatingAssignments: {
[seatNumber: string]: string;
} = {
"34D": "Kim",
"34E": "Loco",
};
반응형
'FrontEnd > TypeScript' 카테고리의 다른 글
[TypeScript] 비동기 프로그래밍, 동시성과 병렬성 (0) | 2023.06.07 |
---|---|
[TypeScript] 에러 처리 (0) | 2023.06.05 |
[TypeScript] 가변성(슈퍼타입/서브타입 파악하기) & 할당성 & 타입 넓히기 (0) | 2023.06.03 |
[TypeScript] 함수의 타입 (0) | 2023.06.03 |
[TypeScript] 클래스와 인터페이스 (0) | 2023.05.31 |