코딩/Typescript

타입스크립트(Typescript) 강좌 1편

드리프트 2021. 10. 23. 10:57
728x170

 

 

 

안녕하세요?

 

오늘은 드디어 새로운 강의를 시작하게 되었습니다.

 

최근에 React, NextJS를 이용하면서 Typescript의 위력을 다시 한번 느꼈었는데요.

 

타입스크립트는 다들 아시다시피 자바스크립트의 Super-set 이란 느낌입니다.

 

타입스크립트의 최대 장점은 type을 지정할 수 있고 거기에 따라 일반 자바스크립트에서 발생하는 type 관련 에러를 방지해 준다는 점에서 큰 효과를 볼 수 있는데요.

 

이 점이 결과적으로 코드를 더 빨리 짤 수 있게 도와주는 효과를 보게 됩니다.

 

자, 지금까지 자바스크립트를 배워왔던 분들도 이제는 타입스크립트를 저랑 같이 배워 볼까요?

 

mkdir typescript-tutorial
cd typescript-tutorial
code .

 

폴더를 만들고 그 폴더에 들어가서 VSCode를 실행해 볼까요?

 

이제 빈 워크스페이스가 나오는데요.

 

tutorial-1.js라는 파일을 만들어 볼까요?

 

// tutorial-1.js

let userName = "squid";
let userLoggedIn = true;

userLoggedIn += " game";

console.log(userLoggedIn);

node로 실행 결과까지 보여 줬는데요.

 

userLoggedIn 은 true로 타입이 boolean입니다.

 

그런데 자바스크립트 덧셈에서는 boolean 타입은 toString() 프로퍼티(property) 때문에 문자열과의 덧셈에서 자동으로 문자열로 바뀝니다.

 

그래서 결과 값이 true game이 나왔는데요.

 

자바스크립트의 이상한 덧셈에 대해서 더 궁금하시면 제가 예전에 쓴 아래 링크를 보시기 바랍니다.

 

https://cpro95.tistory.com/61

 

자바스크립트의 덧셈 연산 완벽 분석

NodeJS, DenoJS, TypeScript 모두 최근 가장 핫한 프로그래밍 언어인데요! 모두 자바스크립트입니다. 자바스크립트가 브라우저에서만 머물다가 NodeJS가 나오면서 본격적으로 유명해지기 시작했는데요.

cpro95.tistory.com

 

마우스를 VSCode에서 userLoggedIn 변수 위에 가져다 잠시 놓아 볼까요?

 

자바스크립트는 변수의 타입을 기본적으로 추측(infer)할 수 있습니다.

 

그래서 위와 같이 보시면 userLoggedIn은 boolean 이란 부울린 타입으로 추측하고 있습니다.

 

코드가 짧고 명확할 경우 이런 방식은 코드 작성에 도움이 되는데요.

 

코드가 커지고 그러면 나중에 타입 에러 때문에 엉뚱한 결과를 가져오기 때문에 최근 타입스크립트가 각광받고 있는 게 아닐까 싶습니다.

 

그럼 이제 본격적으로 Typescript 개발로 바꿔서 진행해 볼까요?

 

타입스크립트 코드를 작성하려면 관련 패키지를 설치해야 되는 돼요.

 

npm install typescript ts-node -D

 

typescript 패키지는 다 아실 테고, ts-node 패키지는 node처럼 명령어 줄에서 바로 타입스크립트 코드를 실행해 볼 수 있는 패키지입니다.

 

이게 없으면 우리는 tsc라는 타입스크립트 컴파일러를 통해 ts 파일을 js 파일로 변환한 후 다시 node로 실행해야 되는 불편함이 있죠.

 

이제 타입스크립트를 초기화해야 하는데요.

 

다음과 같이 실행하시면 됩니다.

 

npx tsc --init

 

그러면 같은 폴더에 tsconfig.json 파일이 생기는데요.

 

이게 타입스크립트 컴파일 옵션 파일입니다.

 

일단 지금은 건드리지 마시고 다음과 같이 실행해 볼까요?

 

ts-node tutorial-1.js

우리가 ts-node를 global 하게 인스톨한 게 아니라서 npx 명령어를 넣어줘야 합니다.

 

일단 실행 결과를 보시면 node로 실행한 것과 차이가 없는데요.

 

왜 그럴까요?

 

바로 tutorial-1 파일의 확장자가. js라서 그렇습니다.

 

그럼 이 파일의 확장자를. ts로 바꿔 볼까요?

 

벌써부터 에러 메시지가 뜨고 난리네요.

 

에러코드가 영어로 나오는데요. 저는 영어 공부 좀 할 겸 항상 영어로 보고 있는데요. 강의를 위해 한글로 바꿔보겠습니다.

 

Cmd + Shift + P를 눌러서 configure display language를 고르면 됩니다.

 

 

이제 에러 메시지가 한글로 나옵니다.

 

'string' 형식은 'boolean' 형식에 할당할 수 없습니다.ts(2322)

 

에러의 메시지도 명확합니다. string 타입을 userLoggedIn 같은 boolean 타입에 넣을 수 없다는 뜻이죠.

 

그럼 컴파일할 때는 어떻게 나올까요?

 

 

아까와 같은 에러 메시지입니다.

 

이렇게 타입스크립트는 타입과 관련된 많은 에러를 사전에 방지해주고 컴파일도 못하게 함으로 코딩할 때 굉장히 도움이 되겠죠.

 

타입스크립트는 자바스크립트를 C나 C++, Java 같은 정적 타입 컴파일러가 되게 만들어 주는 아주 강력한 도구인 겁니다.

 

계속해서 타입(Type) 관련 에러가 나오고 있는데요.

 

타입스크립트나 자바스크립트는 변수의 Type을 추론(추측) Infer 합니다.

 

그런데 타입스크립트에서는 변수의 Type을 미리 지정할 수 있게 하는데요

 

VSCode의 도움말처럼 변수명 뒤에 콜론(:)을 넣고 그다음에 타입(Type)을 넣으면 됩니다.

 

let userName: string = "squid";
let userLoggedIn: boolean = true;

userLoggedIn += " game";

console.log(userLoggedIn);

 

위 코드를 보시면 userName은 : string 형식으로 타입(Type)을 string으로 지정했습니다.

 

userLoggedIn은 : boolean으로 타입(Type)을 boolean으로 지정했습니다.

 

이렇게 하니까 뭔가 코딩할 때 더 명확하지 않은가요?

 

이제 에러가 뭔지 알아냈으니까 수정해 볼까요?

 

let userName: string = "squid";
let userLoggedIn: boolean = true;

userName += " game";

console.log(userName);

 

userLoggedIn 변수 대신 userName 변수로 대체했더니 에러가 사라졌습니다.

 

왜냐하면 userName 변수는 string 타입이기 때문입니다.

 

 

이제 잘 작동되네요.

 

그럼 자바스크립트의 타입은 어떤 게 더 있을까요?

 

 

number 타입입니다. 숫자를 나타내죠.

 

RegExp라는 정규식 표현도 타입이 있습니다. 그래서 아래와 같이 하면 됩니다.

 

 

 

이제 배열을 볼까요?

 

const names = userName.split(" ");

 

userName 이란 문자열을 split 함수를 이용해서 분해해서 배열에 넣는 코드입니다.

 

names의 타입은 뭘까요?

 

string []이라고 나오네요

 

타입스크립트에서의 배열 선언하는 방법입니다.

 

타입 뒤에 []를 붙이면 됩니다.

 

이제 다시 코드를 써 볼까요?

 

const names: string[] = userName.split(" ");

 

이렇게 [] 방식 말고 제네릭 방식을 쓸 수 도 있습니다.

 

const names2: Array<string> = userName.split(" ");

 

결과는 똑같이 string[]로 나오네요.

 

타입스크립트는 배열에 있어 다음과 같이 에러를 보여줍니다.

 

const myNumbers: Array<number> = [1, 2, 3, "4"];

 

 

number 형식의 배열에 string 형식을 할당할 수 없다고 명확하게 에러를 뿜어주네요.

 

 

이제 자바스크립트 객체를 알아볼까요?

 

const myShow = {
    first: "squid",
    second: "name"
}

 

myShow라는 자바스크립트 객체입니다.

 

myShow에 마우스를 갖다 놓아 볼까요?

 

myShow의 타입에 대해 아래와 같이 보여줍니다.

 

 

어떤가요?

 

myShow는 first와 second 가 각각 string인 타입을 갖는 객체라는 뜻입니다.

 

이 객체가 가지고 있는 멤버와 그 타입을 명확하게 보여주죠.

 

그래서 우리는 다음과 같이 미리 객체의 타입을 지정할 수 있습니다.

 

const myShow: {
    first: string;
    second: string;
} = {
    first: "squid",
    second: "name"
}

이제 myShow 라는 객체는 first와 second라는 두 개의 멤버만 있어야 됩니다.

 

한번 에러를 일으켜 볼까요?

 

개체 리터럴에 third 형식을 지정할 수 없다고 나옵니다.

 

왜냐하면 myShow 형식을 first, second 가 string이라고 지정했으니까요?

 

어떤가요? 아주 좋은 기능이죠.

 

그러면 myShow라는 객체를 만들고 여기저기 써야 할 때 계속 타입 지정을 아래와 같이 해야 할까요?

 

const myShow: {
    first: string;
    second: string;
}

 

코드도 길어지고 미관상 안 좋아지는데요.

 

타입스크립트에서는 interface를 지원해 줍니다.

 

그래서 myShow 객체의 타입을 interface로 지정하는 겁니다.

 

interface ShowProps {
    first: string;
    second: string;
}

 

위 코드가 interface 코드입니다.

 

ShowProps 인터페이스를 만든 거죠.

 

interface ShowProps {
    first: string;
    second: string;
}

const myShow: ShowProps = {
    first: "squid",
    second: "game"
}

 

어떤가요? 굉장히 직관적이지 않은가요?

 

이렇게 ShowProps 인터페이스를 만들어 놔서 코드 여러 곳에 사용할 수 도 있습니다.

 

이제 코드 작성할 때 보시면 다음과 같이 VSCode의 인텔리 센스가 도와주는데요.

 

 

어떤가요? myShow라는 변수는 interface에 의해 first, second 두 개의 멤버 변수가 있다고 지정했기 때문에 인텔리 센스가 알아서 보여주고 있습니다.

 

그럼 이제 다음 예제로 넘어가 볼까요?

 

const ids = {
    10: "a",
    20: "b"
}

ids[30] = "c";

 

ids라는 객체를 정의하고 그다음 줄에 하나를 추가했는데요.

 

아래처럼 에러가 났습니다.

 

 

왜냐하면 ids의 타입을 지정하지 않았기 때문에 타입스크립트는 벌써 추론해버렸는데요.

 

{ 10: string; 20: string;} 형식으로 추론해 버렸습니다.

 

그래서 ids[30]에 더 이상 추가할 수 없는데요.

 

이럴 때는 다음과 같이 하면 됩니다.

 

const ids: Record<number, string> = {
    10: "a",
    20: "b"
}

ids[30] = "c";

 

Record라는 제네릭을 이용하면 됩니다. key : value 타입을 이용할 때 쓰는 제네릭입니다.

 

타입스크립트에서 제공하는 타입이죠.

 

 

그래서 ids[30] = "c"라는 코드에 에러가 사라진 겁니다.

 

Record 타입을 이용하면 다음 코드에서 아주 유용한데요.

 

 

조건식에서 에러를 바로 보여줍니다.

 

왜냐하면 number : string 매칭 방식의 Record 이기 때문이죠.

 

그래서 다음과 같이 ids[30] === "D"라고 해야 에러 코드가 없어집니다.

 

타입스크립트는 이렇게 에러를 미리 방지할 수 있어 좋은데요.

 

이제 loops 쪽을 알아 볼가요?

 

for (let i = 0; i < 10; i++) {
    console.log(i)
}

뭔가 문제가 없어 보입니다.

 

for 문에서 i 변수의 타입을 지정해야 하는데 타입스크립트가 정확히 i 변수는 nubmer 추론하기 때문에 이런데 까지 우리가 다음과 같이 할 필요는 없을 거 같네요.

 

 

다음 코드도 볼까요?

 

[1, 2, 3].forEach(v => console.log(v))

배열의 forEach함수입니다. 이때 v 도 명확히 아래와 같이 number 타입으로 추론되기 때문에 큰 문제가 없어 보입니다.

 

 

map 함수를 볼까요?

 

const returnValue = [4, 5, 6].map(v => v * 10)

타입스크립트는 꽤 똑똑하기 때문에 아래 그림처럼 리턴 타입도 정확히 잡아주고 있습니다.

 

리턴 타입이 number[] 배열인 거죠.

 

 

 

 

그러면 다음일 경우 어떨까요?

 

const returnValue = [4, 5, 6].map(v => `${v * 10}`)

 

리턴 값을 스트링 템플릿으로 지정했습니다.

 

string[] 형식이라고 아주 잘 추론하고 있습니다.

 

그러면 returnValue에 returnVale : number[] 라고 타입을 지정하면 어떨까요?

 

당연히 에러가 나겠죠.

 

 

이렇게 타입스크립트는 우리가 코딩할 때 문제가 될 수 있는 문제를 사전에 보여줌으로써 코딩을 안전하게 도와주는데요.

 

어떤가요? 앞으로 계속 타입스크립트만 써야겠죠?

 

그러면 이 코드를 컴파일해볼까요?

 

npx tsc tutorial-1.ts

 

이렇게 하면 tutorial-1.js 파일이 생성됩니다.

 

// 컴파일된 자바스크립트 코드

var userName = "squid";
var userLoggedIn = true;
userName += " game";
console.log(userName);
var myValue = 10.1;
var myRegex = /foo/;
var names = userName.split(" ");
var names2 = userName.split(" ");
var myNumbers = [1, 2, 3];
var myShow = {
    first: "squid",
    second: "game"
};
var ids = {
    10: "a",
    20: "b"
};
ids[30] = "c";
if (ids[30] === "D") {
}
for (var i = 0; i < 10; i++) {
    console.log(i);
}
[1, 2, 3].forEach(function (v) { return console.log(v); });
var returnValue = [4, 5, 6].map(function (v) { return "" + v * 10; });

 

어라, 쉽게 이해할 수 있겠는데요.

 

// 타입스크립트 코드

let userName: string = "squid";
let userLoggedIn: boolean = true;

userName += " game";

console.log(userName);

let myValue: number = 10.1;

let myRegex: RegExp = /foo/;

const names: string[] = userName.split(" ");

const names2: Array<string> = userName.split(" ");

const myNumbers: Array<number> = [1, 2, 3];

interface ShowProps {
    first: string;
    second: string;
}

const myShow: ShowProps = {
    first: "squid",
    second: "game"
}

const ids: Record<number, string> = {
    10: "a",
    20: "b"
}

ids[30] = "c";

if (ids[30] === "D") {

}

for (let i = 0; i < 10; i++) {
    console.log(i)
}

[1, 2, 3].forEach(v => console.log(v))

const returnValue: string[] = [4, 5, 6].map(v => `${v * 10}`)

 

시간 나시면 자바스크립트 코드와 타입스크립트 코드를 비교해 보시기 바랍니다.

 

오늘은 타입스크립트의 타입 관련해서 알아봤는데요.

 

다음 시간에는 타입스크립트 함수에 대해 알아보도록 하겠습니다.

그리드형