-
[TypeScript] 타입스크립트 - Installation & Basic TypesFrontend 2020. 1. 27. 17:26
JavaScript: loosely typed or a dynamic language
자바스크립트는 느슨한 타입 언어, 혹은 동적 언어라고 불린다. 즉, 변수의 타입을 미리 선언하지 않아도 코드가 해석될때 자동으로 파악이 된다. 그 말은 같은 변수에 여러 타입을 넣을 수 있다는 뜻이다. 그러니까 var a 라고 변수를 선언하면 그 변수에 숫자든 문자든 배열이든 함수든 원하는 타입을 모두 넣을 수 있다는 뜻이다.
var a = 123; // a is now a number a = 'string'; // a is now a string a = { b: 1 }; // a is now an object
이 부분이 매우 편리할 수도 있겠지만, 반대로 여러가지 버그를 야기하는 경우가 많았다.
개발자가 의도하지 않은 타입의 값이 주입되어도 자바스크립트는 에러로 인지하지 않기 때문이다.
예를 들어서 2개의 숫자 타입 인자를 받아 덧셈을 하는 간단한 함수를 만든다고 생각해보자.
function addNumber (x, y) { return x + y; }
만약에 x와 y에 의도한대로 숫자가 들어온다면 원하는대로 잘 작동하겠지만
둘 중에 하나라도 다른 타입의 값이 들어오면 생각치못한 결과물이 나올 것이다.
addNumber(1, 2); // 3 addNumber('hello', 1); // hello1
타입스크립트는 기본적으로 이러한 상황들을 사전에 막기 위해서 생겨났다.
만약에 내가 변수나 인자에 미리 타입을 지정해두고
원하지 않는 타입의 값이 들어왔을때 에러라고 인지하고 메시지를 띄워준다면
개발하는 도중에 예상치못했던 상황의 발생을 많이 막아줄 것이다.
Installation
그냥 간단하게 javascript 파일에 타입스크립트를 적용해보는 방법은 매우 쉽다.
$ npm install -g typescript
위 터미널 명령어로 typescript Node.js 패키지를 설치한다.
example.ts:
function addNumber(x: number, y: number): number { return x + y; } let result: number = addNumber(1, 2); console.log(result);
이제 원하는 폴더에 .ts 파일을 생성하고 아까 위에서 만들었던 함수에 typescript을 적용해주었다.
$ tsc example.ts
원하는 폴더에 .ts 파일을 생성한 후 위 명령어로 컴파일한다.
그러면 같은 경로에 example.js 파일이 생성된 것을 볼 수 있다.
파일을 열어보면 다음과 같이 JavaScript로 변환되어 있는 것을 확인할 수 있다.
example.js
function addNumber(x, y) { return x + y; } var result = addNumber(1, 2); console.log(result);
이제 example.js를 실행해보면 원하는 결과가 나온다.
function addNumber(x: number, y: number): number { return x + y; } let result: number = addNumber(1, 2); console.log(result); let result2: number = addNumber(1, 'hello'); console.log(result2);
만약에 number type 대신 string을 인자로 넘겨준다면 어떻게 될까?
바로 이렇게 컴파일 단계에서 에러가 발생한다.
Basic Types
그럼 이제 Typescript에서 사용하는 basic types들에 대해 알아보자.
1. Boolean
2. Number
3. String
4. Array
5. Tuple
6. Enum
7. Any
8. Void
9. Null, Undefined
10. Never
11. Object
Boolean
true와 false로 이루어진 Boolean type이다.
let isTrue: boolean = true; let isFalse: boolean = false;
Number
숫자 타입이다. 10진수 뿐만 아니라 2진수, 8진수, 16진수 모두 Number type에 해당한다.
let num: number = 10;
String
텍스트 데이터를 정의하는 문자 타입이다. ""나 '', 혹은 ``로 감싸여진 데이터를 말한다.
let firstName: string = 'Jane'; let age: number = 20; let sentence: string = `I'm ${firstName}. I'm ${age} years old.`;
Array
배열 타입이다. 배열 안의 item들이 어떤 타입이냐에 따라 다음과 같이 사용할 수 있다.
let numList: number[] = [1, 2, 3]; let strList: Array<string> = ['a', 'b', 'c'];
number[] 혹은 Array<number>로 사용할 수 있다.
만약에 배열 안에 여러 가지 타입이 섞일 수 있다면 any를 이용하면 된다.
let anyList: any[] = [1, 'a', true]; let anyList2: Array<any> = ['d', '5', 5, false];
Tuple
tuple은 정해진 고정된 element 개수를 가지는 배열을 말한다.
let list: [string, number] = [1, 2, 'a']; // error let list2: [string, number] = ['a', 1, 2]; // error let list3: [string, number] = ['a', 1]; // OK
각 요소 개수만큼 타입을 지정할 수 있고, 정확하게 매칭이 안되면 에러가 발생한다.
Enum
C#에도 존재하는 enum은 일종의 numeric values 세트이다.
enum Fruit { Orange, Apple, Banana } let breakfastIndex: Fruit = Fruit.Apple; // 1 let breakfast: string = Fruit[2] // Banana
위 예시처럼 사용할 수 있는데, 맨 위가 0번이고 순서대로 1씩 증가한 순번이 매겨진다.
enum Fruit { Orange = 1, Apple, Banana } let breakfastIndex: Fruit = Fruit.Apple; // 2 let breakfast: string = Fruit[1] // Banana
처음 시작하는 번호를 원하는 번호로 설정할 수 있다. 아래 value들은 1씩 증가한다.
enum Food { Sandwich = 1, Pasta = 3, Hamburger = 5 } let lunchIndex: Food = Food.Pasta; // 3 let lunch: string = Food[1]; // Sandwich
아니면 각각 다른 숫자를 지정할 수 있다.
enum Desert { Cake = 'CHOCOLATE_CAKE', Cookie = 'BUTTER_COOKIE', Candy = 'ORANGE_CANDY' } let snackIndex: Desert = Desert.Candy; // ORANGE_CANDY
string type의 enum도 존재한다. string enum은 number enum과는 달리 자동으로 증가하지 않는다.
string enum은 serialize가 잘 된다는 이점이 있다.
* serialize: data structure나 object의 state를 저장/전송할 수 있는 포맷으로 바꾸고 후에 이를 같은 환경 또는 다른 환경에서 다시 semantically identical한 object로 복구시키는 process.
Any
우리가 application을 작성할때 type을 알 수 없는 변수들이 있다. 특히 동적으로 생성되는 요소들이 그렇다. 이렇게 컴파일 단계에서 type을 검사하고 싶지 않을때 사용할 수 있는 것이 any이다.
let anyType: any = 'string'; anyType += 1; // string1 anyType = false; // false
Void
void는 어떻게보면 any와 반대인 경우라고 할 수 있다. void는 어떤 type도 아닌 경우에 사용한다. 주로 사용하는 경우는 return 값이 없는 함수의 return type으로 설정하는 경우이다.
function hasNoReturnValue(): void { console.log('Hi there!') } let a: void = null; a = undefined;
void로 타입을 지정하는 것은 그렇게 유용하진 않다. 왜냐면 오직 null이나 undefined만 할당할 수 있기 때문이다.
Null / Undefined
타입스크립트에는 null과 undefined type이 각각 존재한다. void와 같이 유용하게 쓰이는 타입들은 아니다.
let b: undefined = undefined; let c: null = null; b = null; c = undefined;
위 예시처럼 undefined 타입으로 지정한 변수에 null을 할당할 수도 있고, null 타입으로 지정한 변수에 undefined를 할당할 수도 있다.
Never
never type은 절대 발생하지 않을 타입을 지정할때 사용한다. 항상 예외의 상황이나 에러를 던지는 함수에 return type으로 never를 지정할 수 있다. never type은 다른 모든 타입의 subtype이지만 어떤 타입도 never의 subtype이 될 수 없다.
function error(message: string): never { throw new Error(message); } function fail() { return error('Something went wrong'); }
Object
object는 non-primitive type을 대표한다. 즉 number, string, boolean, bigint, symbol, null, undefined를 제외한 모든 타입을 object type이라고 할 수 있다.
let d: object = {a: 1}; d = ['a', 'b', 1]; d.forEach((elem) => { console.log(elem); }); // error
object 타입에 배열을 할당한 경우 에러가 발생하진 않지만 object type으로 인지되기 때문에
Array.prototype에 존재하는 method를 사용할 수는 없다.
let realArray: any[] = [1, 2, 'hi']; realArray.forEach((elem) => { console.log(elem); });
이렇게 배열로 선언한 경우에는 Array.prototype method를 사용할 수 있다.
let d: object = {a: 1}; d = function(): void { console.log('hello'); } d(); // error
object 타입에 함수를 할당한 경우 에러가 나진 않지만
앞서 말한 예시와 같은 이유로 함수를 실행할 수는 없다.
let sayHello: any = d; sayHello();
반면에 any type인 변수에 할당한 경우에는 함수를 실행할 수 있다.
Reference
https://www.typescriptlang.org/docs/handbook/basic-types.html
반응형'Frontend' 카테고리의 다른 글
[React] Typescript와 Redux hooks를 이용하여 간단한 TODO LIST 만들기 (253) 2020.02.23 [React] Context Api에 대해서 (252) 2020.02.09 [React/Node.js] Chat App, Typing Indicator - 채팅 앱에서 대화 상대가 텍스트를 입력 중일 경우 표시해주는 기능 구현하기 (842) 2019.10.06 [React] React-Map-Gl 라이브러리를 사용하여 지도 띄우고 마커 표시하기 (2044) 2019.08.30 [React] React.js와 firebase를 사용하여 간단한 메모 앱 만들기[2] - 메모 저장 및 삭제하기 (609) 2019.08.30 COMMENT