코드스테이츠-부트캠프 [TypeScript] 기초(1)

김희목·2024년 3월 31일
0

코드스테이츠

목록 보기
51/56

TypeScript란

TypeScript는 마이크로소프트에서 개발한 JavaScript의 상위 집합(Superset) 언어입니다.

JavaScript에 정적타입 검사와 클래스 기반 객체 지향 프로그래밍 등의 기능을 추가하여 개발된 언어로, JavaScript가 발전하면서 생긴 단점을 보완하기 위해 등장하게 되었습니다.


TypeScript의 등장 배경

TypeScript를 이야기하기에 앞서, JavaScript에 대해 먼저 이야기해 보겠습니다.

JavaScript는 처음에는 브라우저에서만 동작하는 스크립팅 언어로 만들어졌었습니다. 시간이 점점 흐르고, JavaScript로 웹 애플리케이션의 상호작용이 증가하면서, 웹 애플리케이션이 필요로 하는 JavaScript 코드의 양이 폭발적으로 늘어나게 되었습니다.

이로 인해 JavaScript의 한계가 부각되기 시작했습니다. JavaScript는 동적 타입이 결정되어 유연하고, 다양한 라이브러리와 프레임워크를 사용할 수 있는 장점이 있지만, 타입의 명시성이 부족하다는 단점이 있습니다.

타입의 명시성이 부족하게 되면 예상치 못한 결과를 초래할 수 있습니다. 아래는 그 예시입니다.

let add = (x, y) => {
	return x + y;
}

add(5, "7");

위의 코드는 add 함수에 숫자 5와 문자열 "7"을 전달인자로 전달하여 덧셈을 수행하고 있습니다. 이렇게 되면 결과는 "57"이 나옵니다.

이런 식으로 JavaScript는 문자열과 숫자를 더할 경우, 숫자 타입의 인수 쪽을 강제적으로 타입 변환해 문자열을 만듭니다. 이렇게 JavaScript는 함수나 변수의 타입을 명시적으로 지정하지 않아도 동작하는 경우가 많아 예상치 못한 결과를 초래하게 됩니다. 이런 문제점을 보완하기 위해 TypeScript라는 언어가 등장하게 되었습니다.


TypeScript를 사용했을 시 장점

TypeScript는 정적타입 검사 기능을 제공하며, 코드의 가독성과 유지 보수성을 높여줍니다. 이를 통해 개발자는 런타임 에러를 최소화하고, 코드 작성 시간을 단축하며, 협업 시 코드의 가독성을 높일 수 있습니다.

또한 TypeScript는 ES6의 문법을 포함한 최신 JavaScript 문법을 지원하며, 인터페이스(Interface), 제네릭(Generic), 데코레이터(Decorators) 등의 기능을 제공하여 객체 지향 프로그래밍을 보다 쉽게 할 수 있도록 도와줍니다.

아래는 인터페이스(Interface)를 사용하여 코드의 가독성을 높인 예시입니다.

interface User {
  id: number;
  name: string;
}

function greetingUser(user: User) {
	 console.log(`Hello, ${user.name}!`)
}

const parkUser = {
	id: 1,
  name: "박해커"
};

greetingUser(parkUser);

위의 코드는 User 인터페이스를 정의해 User의 정보를 좀 더 쉽게 파악할 수 있습니다. 그리고 greetingUser 함수에도 매개변수로 User 타입을 사용해 이 함수가 어떤 타입의 인자를 받고 있는지 명확히 표현하고 있습니다.

이렇게 TypeScript를 사용하면 코드의 가독성을 높일 수 있습니다. 또한 타입을 명시함으로써 코드의 의도 또한 명확해지기 때문에 다른 개발자가 코드를 이해하고 수정하기 쉬워지며, 런타임 에러를 미리 방지할 수 있기 때문에 유지보수성 또한 높아집니다.


Boolean(불리언) 타입

기본적인 데이터 타입으로, JavaScript에서도 마찬가지로 boolean 값이라고 불리는 참(true), 거짓(false) 값입니다.

let isShow: boolean = true;
let isDone: boolean = false;

Number(숫자) 타입

TypeScript에서 Number 타입을 선언하는 방식은 아래와 같습니다. JavaScript와 마찬가지로 TypeScript 또한 정수와 실수의 구분 없이 Number 타입 하나로 표기합니다. TypeScript는 이 외에도 추가로 bigint를 지원합니다.

let number1: number = 5;
let number2: number = 0.7;

String(문자열) 타입

TypeScript는 JavaScript처럼 큰따옴표(")나 작은따옴표(')를 사용하여 문자열 데이터를 표현합니다. 또한 백틱을 사용한 문자열인 템플릿 리터럴을 사용하면 여러 줄에 걸쳐 문자열을 작성할 수 있습니다.

let firstName: string = "coding";
let lastName: string = 'kim';
let longString: string = `Kimc

Array(배열) 타입

TypeScript는 JavaScript처럼 값들을 배열로 다룰 수 있게 할 수 있으며, 두 가지 방법으로 배열 타입을 선언해 사용할 수 있습니다.

//첫 번째 방법
let items: string[] = ["apple", "banana", "grape"];

//두 번째 방법
let numberList: Array<number> = [4, 7, 100];

첫 번째 방법은 배열의 요소들을 나타내는 타입 뒤에 배열을 나타내는 []을 쓰는 것입니다. 이어 두 번째 방법은 제네릭 배열 타입을 사용하는 것입니다. Array를 먼저 작성한 뒤, <> 안에 배열의 요소들을 나타내는 타입을 작성합니다. 제네릭은 이후 챕터에서 배우게 됩니다. 배열 타입은 기본적으로 하나의 타입만 작성하게 되어 있으며, 타입을 혼용해서 작성하는 것은 불가능합니다.

Tuple(튜플) 타입

TypeScript에서 튜플 타입을 사용하면 요소의 타입과 개수가 고정된 배열을 표현할 수 있습니다.

let user: [string, number, boolean] = ["kimcoding", 20, true];

모든 요소가 전부 같을 필요는 없지만, 배열의 index마다 타입이 정해져 있기 때문에 정확한 index에 접근할 필요가 있습니다.

console.log(user[2].toString());

이렇게 user[2]에 접근하게 되면, user[2]에 있는 요소는 boolean 타입이기 때문에 타입 에러가 발생합니다.

JavaScript에서도 튜플 타입을 지원하며, JavaScript에서의 튜플 또한 여러 개의 값을 가진 배열을 나타내는 데에 사용합니다. 그러나 JavaScript에서는 튜플 타입을 명시적으로 선언할 수 없기 때문에 개발자가 직접 튜플의 각 요소의 타입을 확인하고 유추해야 하므로 타입 에러가 더 쉽게 발생합니다. TypeScript의 등장 배경 중 하나인 타입 에러를 방지하고자 한 이유 중 하나이기도 합니다.

Object(객체) 타입

TypeScript에서 객체는 JavaScript와 마찬가지로 원시 타입이 아닌 타입을 나타냅니다. JavaScript에서 Object(객체) 타입은 프로퍼티를 가지는 JavaScript의 값을 말하며 typeof 연산자를 사용했을 때 “object”을 반환하는 모든 타입을 의미합니다.

JavaScript의 원시 타입에는 number, string, boolean, undefined, null, symbol이 있습니다.

let obj: object = {};

TypeScript에서 object 타입은 모든 객체를 수용하는 타입으로, 객체의 프로퍼티 타입들이 any로 지정되기 때문에 어떠한 프로퍼티라도 추가할 수 있습니다. 그러나 이는 타입 안정성을 보장하지 않기 때문에 추천하는 방법은 아닙니다.

따라서 객체의 프로퍼티 타입들을 각기 명시해 주는 것이 훨씬 좋습니다. 객체는 이런 방식으로 key-value에 구체적인 타입까지도 지정할 수 있습니다.

let user: {name: string, age: number} = {
	name: "kimcoding",
	age: 20
}

Any 타입

간혹 애플리케이션을 만들 때, 알지 못하는 타입을 표현해야 할 때도 있습니다. 클라이언트에서 유저로부터 받은 데이터 및 서드파티 라이브러리에서 들어오는 값인 경우 개발자가 알지 못하는 타입일 수 있는데, 타입 검사를 하지 않고자 할 때 any 타입을 사용할 수 있습니다.

let maybe: any = 4;

any 타입을 사용하게 되면, 변수에 값을 재할당하는 경우 타입을 명시한 변수와 달리 타입에 구애받지 않고 값을 재할당할 수 있게 됩니다.

let obj: object = {};

//에러가 납니다.
obj = "hello";

let maybe: any = 4;

//정상적으로 동작합니다.
maybe = true;

또한 엄격한 타입 검사를 진행하지 않기 때문에, 실제 할당된 값이 가지지 않는 메서드 및 프로퍼티로 접근해도 에러가 나지 않습니다. 대신, 실제 할당된 값이 가지지 않는 메서드 및 프로퍼티이기 때문에 반환되는 값은 undefined입니다.

let maybe: any = 4;

//undefined로 출력됩니다.
console.log(maybe.length);

또한 any 타입은 타입의 일부만 알고, 전체는 알지 못할 때 유용합니다. 예를 들어서 여러 타입이 섞인 배열을 받고자 할 때 유용합니다.

let list: any[] = [1, true, "free"];

//any로 다루고 있기 때문에 index 1번째 요소가 boolean 타입이지만 number 타입으로 재할당할 수 있습니다. 
list[1] = 100;

실습 - 타입

/* boolean형 */
let isDone : boolean = false;
let isShow : boolean =  true;

console.log(isDone);
console.log(isShow);

/* 숫자형 */
let num1 : number = 7;
let num2 : number =  0.6878;

console.log(num1);
console.log(num2);

/* 문자형 */
let str : string =  'hello';

console.log(str);

/* 숫자형 배열의 타입을 정하는 2가지 방법 */
let list1 : Array<number> =  [1, 2, 3];
let list2 : number[] = [1,2,3];

console.log(list1);
console.log(list2);

/* 문자형 배열의 타입을 정하는 2가지 방법 */
let list3 : string[] = ['banana', 'apple', 'mango'];
let list4 : Array<string> = ['banana', 'apple', 'mango'];

console.log(list3);
console.log(list4);

/* 튜플 */
let list5 : [number,string,boolean] =  [1, 'banana', true];

console.log(list5);

/* 객체형 타입을 정하는 2가지 방법 */
let obj : object = {};
let obj2 : { name: string, age:number, isDeveloper:boolean} = {
  name: 'kimcoding',
  age: 20,
  isDeveloper: true,
};

console.log(obj);
console.log(obj2);

0개의 댓글