Type#
타입은 value가 가진 다양한 속성,메서드를 지칭하는 지름길이라고 볼 수 있다.
함수로서의 타입, 클래스로서의 타입 등등 이 있다.
variable(변수) : string, number, boolean, null, undefined, object, function, array 등등..
“red” 를 보면
- string 이다.
- string이 가진 모든 개체와 method들 이다.
두 방법으로 대답할 수 있다. 예를 들어, string은 charAt(), indexOf() 등 다양한 method를 가진다. 이걸 매번 다 설명하지 않고 모두를 통칭하기 위한 것이 Type 이다.
따라서 Type은 하나의 값이 가지는 다양한 속성과 메소드를 지칭하기 위한 지름길인 것이다.
Typescript에서 모든 값은 type을 가진다.
Primitive Types#
기본적인 것들(number, string, null, 등등)
Object Types#
내가 만들거나 내장된 것(functions,arrays,classes,objects 등)
Object Types 를 통해 하나의 값이 다른 유형을 지니는 것처럼 속일 수 있다.
Type을 통해
- 컴파일러는 코드의 오류를 잡아낸다.
- 다른 사람이 내 코드에 어떤 값들이 나타날지 이해할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
| const today = new Date();
today.getMonth(); // today. 을 입력하면 Date의 method들이 자동완성에 뜬다.
const person = {
age: 20 // person에 마우스 커서를 올려보면 age에 number로 type이 자동 부여된다
};
class Color {
}
const red = new Color();
red. // 이렇게 입력하면 자동완성도 뜨지 않고, 오류가 발생한다. 메서드가 없으니까.
|
Type annotation and inference#
Type annotations#
TS에게 변수가 어떤 유형의 값을 나타내는지 말해주기 위한 우리가 작성하는 코드
Type inference : TS가 변수가 어떤 유형의 값을 나타내는지 파악하려하는 것
const : 변수 지정
let : 후에 변수 재지정 가능
Type annotation 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| let apples: number = 5;
let speed: string = 'fast';
let hasName: boolean = true;
let nothingMuch: null = null;
let nothing: undefined = undefined;
// built in objects
let now: Date = new Date();
// Array, 왼쪽에 타입을 적어서 내부 원소의 타입 지정
let colors: string[] = ['red', 'green', 'blue'];
let myNumbers: number[] = [1, 2, 3];
let truths: boolean[] = [true, true, false];
// Classes, 첫 글자만 대문자인 것은 일반적으로 클래스 이름을 나타낸다.
class Car {}
let car: Car = new Car();
// Object literal, 세미콜론(;)으로 분리해야한다.
let point: { x: number; y: number } = {
x: 10,
y: 20,
};
// Function, : 부분이 annotation 이고 '=' 이후로 함수가 시작된다.
const logNumber: (i: number) => void = (i) => {
console.log(i);
};
|
Type inference#
const color = ‘red’; 는 두 부분으로 나뉜다.
const color : Variable Declaration
'red'; : Variable Initialization
let apples: number =5 ; 로 선언 후
apples에 커서를 가져다대면 number가 type으로 뜬다.
let apples = 5; 로 수정해도 똑같이 뜬다. 이것이 type inference
Type annotations 사용하는 경우#
함수가 ‘any’ 타입을 반환하여 값을 명확히 하고싶을 때#
1
2
3
4
5
6
7
8
| // when to use annotations
// 1) Function that returns the 'any' type
const json = '{"x": 10, "y": 20}';
const coordinates = JSON.parse(json); // coordinate : any로 뜬다.
console.log(coordinates); // {x: 10, y:20};
// 수정 후
const coordinates: { x: number; y: number } = JSON.parse(json); // coordinate의 type을 알수있다.
|
TS에서 JSON.parse 는 항상 any타입을 반환한다.
any 타입은 TS가 정확한 타입을 모른다는 것을 의미하다.
any타입에 대해선 TS가 오류를 잡아낼 수 없기 떄문 최대한 지양해야 한다.
변수를 선언하고 나중에 초기화할 때#
1
2
3
4
5
6
7
8
9
10
11
12
13
| // 2) when we declare a variable on one line
// and initalizate it later
let words = ['red', 'green', 'blue'];
let foundWord; // fondWord는 any 타입
for (let i = 0; i < words.length; i++) {
if (words[i] === 'green') {
foundWord = true;
}
}
// 수정 후 : 타입을 선언해준다.
let foundWord: boolean;
|
inference 될 수 없는 타입의 변수를 사용할 때#
1
2
3
4
5
6
7
8
9
10
11
12
| // 3) Variable whose type cannot be inferred correctly
let numbers = [-10, -1, 12];
let numberAboveZero: boolean = false; // false였다가, 0 이하의 수가 나타나면 그 수가 되는 변수
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > 0) {
numberAboveZero = numbers[i]; // boolean으로 선언했기 떄문에 숫자로 설정할 수 없다.
}
}
// 수정 후 : boolean 혹은 number로 설정
let numberAboveZero: boolean | number = false;
|
Type annotation for Function : 함수가 어떤 타입의 인수를 받고 어떤 타입의 값을 반환하는지 작성
1
2
3
| const logNumber: (i: number) => void = (i: number) => {
console.log(i);
};
|
Type inference for functions : 함수가 어떤 타입의 값을 반환하는지 파악
1
2
3
4
5
| const add = (a: number, b: number): number => {
// 오류가 발생한다. number 타입을 반환하지 않고 있기 떄문
// 아래 코드를 작성하면 오류가 고쳐진다. 위에서 말한대로 number를 반환하기 때문
// return a + b;
};
|
TS는 올바른 Type에 대해 판단할 뿐, Logic은 판단하지 않는다.
1
2
3
4
5
6
7
| const subtract = (a: number, b: number) => {
a - b; // return을 하지 않아 void type을 반환한다. annotation을 안했기 때문에 TS는 오류를 발견하지 못한다.
};
const subtract = (a: number, b: number): number => {
a - b; // 함수가 number를 반환한다고 했지만 void를 반환하므로 오류가 감지된다.
};
|
annotation을 통해 TS가 올바르게 반환하는 함수인지 감지하도록 할 수 있다.
Type inference보단 annoation 사용하자
함수의 반환값 annotation 예
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| // void : return하지 않는 함수. null 이나 undefined를 반환해도 된다.
const logger = (message: string): void => {
console.log(message);
};
// never : 함수가 끝까지 도달하지 않음. void로 해도 된다.
const throwError = (message: string): never => {
throw new Error(message);
};
// 에러 메시지 출력 코드 예시
const throwError = (message: string): string => {
if (!message) {
throw new Error(message);
}
return message;
};
// Object destructuring(구조분해)
const todaysWeather = {
date: new Date(),
weather: 'sunny',
};
const logWeather = (forecast: { date: Date; weather: string }): void => {
console.log(forecast.date);
console.log(forecast.weather);
};
// destructuring 후 코드
const logWeather = ({
date,
weather,
}: {
date: Date;
weather: string;
}): void => {
console.log(date);
console.log(weather);
};
logWeather(todaysWeather);
// Destructuring
const profile = {
name: 'alex',
age: 20,
coords: {
lat: 0,
lng: 15,
},
setAge(age: number): void {
this.age = age;
},
};
const { age, name }: { age: number; name: string } = profile;
const {
coords: { lat, lng },
}: { coords: { lat: number; lng: number } } = profile;
|