
TypeScript는 JavaScript의 단점을 보완하기 위해 만들어진 언어로, 정적 타입(static type)을 지원하는 확장된 버전이다.
TypeScript는 JavaScript의 Superset(상위확장)이기 때문에 기존의 자바스크립트 문법을 그대로 사용할 수 있다.
TypeScript 코드는 브라우저에서 직접 실행되지 않고, TypeScript 코드를 JavaScript 코드로 변환하는 컴파일 작업을 거쳐야 한다.
TypeScript는 타입 체크(Type Checking)를 통해 코드의 안정성을 높이고, 개발자가 마치 자바처럼 정적으로 프로그래밍을 할 수 있도록 도와준다.

개념을 통해서도 알 수 있듯이 다양한 이점이 있지만, 구체적으로 정리하자면 아래와 같다.
IDE 및 도구의 지원
타입스크립트는 풍부한 정적 분석을 제공하기 때문에, 통합 개발 환경(IDE)에서 코드 자동 완성, 리팩토링, 디버깅 등의 강력한 기능을 지원한다. 그래서 개발 생산성을 높이고 실수를 줄여준다.
객체지향 프로그래밍 지원
타입스크립트는 클래스, 인터페이스, 제네릭 등과 같은 강력한 객체지향 프로그래밍의 요소들을 지원한다. 그래서 코드의 구조를 더 잘 구성하고 유지보수성을 향상시킨다.
코드 안정성 및 오류 사전 방지
정적 타입 언어로, 컴파일 시간에 타입 체크를 수행하여 코드 실행 전에 타입 관련 오류를 찾아내기 때문에 런타임에서 발생할 수 있는 오류를 사전에 방지할 수 있다.
프로그래머 의도의 명시
타입 어노테이션을 통해 변수, 함수 등에 명시적으로 타입을 지정함으로써 코드의 가독성을 향상시키고, 개발자의 의도를 명확하게 전달할 수 있다.
컴파일은 일반적으로 소스 코드를 바이트 코드로 변환하는 작업을 의미한다.
TypeScript 컴파일러는 TypeScript 파일을 JavaScript 파일로 변환하므로 컴파일보다는 트랜스파일링(Transpiling)이 보다 적절한 표현이라고 한다.
근데 실제로는 컴파일러를 통해 이루어지니까, 컴파일이라는 용어를 사용해도 된다.
그래서 그냥 아무거나 사용할란다 🤪
1. 타입스크립트 전역 설치
$ npm install -g typescript
2. 타입스크립트 버전 확인
$ tsc -v
Version 5.3.3
→ 트랜스파일링 실행을 위해 index.ts 파일을 작성하자!
3. 트랜스파일링 실행
$ tsc 파일명
→ 트랜스파일링된 index.js의 자바스크립트 버전은 ES3다.
(TypeScript 컴파일 타겟 자바스크립트 기본 버전이 ES3)
4. ES6버전으로 트랜스파일링 실행
$ tsc 파일명 -t ES2015
5. 출력 결과
$ node 파일명
→ 매번 옵션을 지정하기 번거로우니, tsc 옵션 설정 파일을 생성하자!
✓ tsc 옵션 설정 (tsconfig.json 생성)
$ tsc --init
✓ 트랜스파일링 실행 (tsconfig.json 적용)
$ tsc
→ tsc 명렁어 뒤에 파일명을 지정하면, tsconfig.json이 무시되고 지정된 파일만 트랜스파일링된다.
→ 파일명을 지정하지 않으면, 프로젝트 폴더 내의 모든 TypeScript 파일이 모두 트랜스파일링된다.
✓ 트랜스파일링 대상 파일 내용이 변경됐을 때 감지해 자동으로 트랜스파일링이 실행된다.
$ tsc --w
또는 tsconfig.json에 watch 옵션을 추가할 수도 있다.
{
// ...
"watch": true
}
// teacher.ts
export class Teacher {
protected name: string;
constructor(name: string) {
this.name = name;
}
sayHoo() {
return '안녕!' + this.name;
}
}
// student.ts
import { Teacher } from './teacher';
class Student extends Teacher {
study(): string {
return `${this.name}는 공부중!`;
}
}
const student = new Student('덕배');
console.log(student.sayHoo());
console.log(student.study());
$ tsc
$ node student
안녕!덕배
덕배는 공부중!
TypeScript는 정적 타입 언어로, 변수와 함수의 타입을 미리 선언하고 이에 따라 컴파일러가 타입을 검사한다. 이를 통해 코드의 안정성을 높이고 오류를 사전에 방지할 수 있다.
아래의 첫번째 함수는 JavaScript 코드이며, 문법상 문제가 없으므로 잘 실행될 것이다. 왜? 자바스크립트의 동적 타이핑(Dynamic Typing)은 변수나 반환값의 타입을 사전에 지정하지 않기 때문이다.
아래의 두번째 함수는 첫번째 함수를 TypeScript의 정적 타입을 사용한 것이다. 정적 타입을 통해 컴파일 단계에서 오류를 포착할 수 있다. 이는 코드의 가독성을 높이고 예측할 수 있게 하며 디버깅을 쉽게 한다.
// javascript
function sum(a, b) {
return a + b;
}
console.log(sum('x', 'y')); // 'xy'
// typescript
function sum(a: number, b: number) {
return a + b;
}
sum('x', 'y');
// error TS2345: Argument of type '"x"' is not assignable to parameter of type 'number'.
Type Annotations은 변수, 함수 매개변수, 함수 반환 값 등에 대한 명시적인 타입 정보를 추가하는 것이다. 이를 통해 개발자는 코드를 읽을 때 명확하게 타입을 이해할 수 있고, 컴파일러는 타입을 검증할 수 있다.
아래의 예제는 함수의 변수 a, b 의 반환 값에 대한 명시적인 타입 정보를 입력했을 때다.
즉, 함수의 매개변수와 반환 값의 타입을 명시적으로 지정한 경우다.
function sum(a: number, b: number): number {
return a + b;
}
타입스크립트의 기본 타입은 크게 12가지가 있다.
타입스크립트가 기본 제공하는 타입은 모두 소문자이며, 아래와 같이 변수명 뒤에 타입을 명시하는 것으로 타입을 선언한다.
선언한 타입에 맞지 않는 값을 할당하면 컴파일 시점에 에러가 발생한다. VSCode를 사용하면 코드를 작성하는 시점에 에러를 발견할 수 있어서 개발 효율이 향상된다.
let str: string = '덕배';
let age: number = 30;
let isLoginUser: boolean = false;
let nullValue: null = null;
// 대부분의 경우, null은 값을 갖는 변수나 변수의 초기값을 선언할 때 사용하기에,
// 변수가 null을 포함할 수 있는지 여부는 타입스크립트가 유추하도록 하는 것이 일반적
let nullValue = null;
let undefinedValue: undefined = undefined;
const obj: object = { key: 'value' };
// 구체적인 속성의 타입을 명시할 수도 있음
const detailObj: { key: string, count: number } = { key: "example", count: 30 };
const arr: number[] = [1,2,3];
const arr2: any[] = [1, 'two', true];
// 제네릭을 사용할 수도 있음
const arr3: Array<number> = [1,2,3];
let arr: [string, number] = ['덕배', 30];
// 정의하지 않은 타입으로 인덱스 접근 시, 오류 발생
arr[1].concat('!'); // Error, 'number' does not have 'concat'
arr[4] = 'hello'; // Error, Property '4' does not exist on type '[string, number]'
enum Color1 {
Red,
Green,
Yellow,
}
let c1: Color1 = Color1.Green;
console.log(c1); // 1
enum Color2 {
Red = 1,
Green,
Yellow,
}
let c2: Color2 = Color2.Green;
console.log(c2); // 2
enum Color3 {
Red = 1,
Green = 2,
Yellow = 4,
}
let c3: Color3 = Color3.Yellow;
console.log(c3); // 4
모든 타입에 대해서 허용하고, 어떤 타입의 값이라도 할당할 수 있다.
타입 추론(type inference)할 수 없거나 타입 체크가 필요 없는 변수에 사용한다.
let anyValue: any = 30;
console.log(anyValue); // 30
anyValue = '덕배 안녕'; // 문자열 할당
console.log(anyValue); // 덕배 안녕
anyValue = true; // 불리언 할당
console.log(anyValue); // true
// 배열 요소가 모든 다른 타입일 때
let mixArray: any[] = [1, '덕배', true];
console.log(mixArray); // [1, '덕배', true]
// 객체의 속성이 모든 다른 타입일 때
let mixObject: any = {
key1: 30,
key2: '덕배',
key3: true,
};
console.log(mixObject); // { key1: 30, key2: '덕배', key3: true }
보이드는 반환 값이 없는 함수의 반환 타입이다.
아래와 같이 return이 없거나, return이 있더라도 반환하는 값이 없으면 함수의 반환 타입을 void로 지정한다.
function example(): void {
console.log('나는 덕배');
}
function example2(): void {
return;
}
// 끝나지 않는 함수
function infinite(): never {
while (true) {
console.log('나는 끝없는 인간');
}
}
// 예외를 던지는 함수
function error(message: '나는 에러'): never {
throw new Error(message);
}
// 이 함수를 호출하면 예외가 발생하고, 함수가 반환하지 않음
error('나는 에러');
타입스크립트는 변수에 대한 타입을 명시하지 않아도 컴파일러가 자동으로 타입을 추론한다.
아래의 예제를 보면 변수 x 에 대한 타입을 따로 지정하지 않아도 x 는 number라고 타입 추론에 의해 변수 타입이 결정된다.
let x = 100; // x는 number 타입
let x = 100; // x는 number 타입
x = '덕배'; // error: Type '"덕배"' is not assignable to type 'number'
타입 선언을 생략하고 값도 할당하지 않아서 타입 추론이 불가하면 any 타입이 된다.
any 타입의 변수는 어떤 타입의 값도 재할당이 가능하다.
let x; // let x: any
x = '덕배';
console.log(typeof x); // string
x = 'true';
console.log(typeof x); // boolean
as 키워드를 사용해 개발자가 해당 타입에 확식이 있을 때 사용하는 방식이다. let a: any = '덕배';
let a = '덕배' as string; // 타입 단언
// 혹은 아래처럼 사용할 수도 있음
let b: number = (a as string).length; // 타입 단언
타입 캐스팅은 타입 단언과 유사하지만, 컴파일러에게 추가적인 정보를 제공해 값의 실제 타입을 변경하도록 한다.
타입 캐스팅은 타입스크립트에서 타입 단언을 사용할 수 없을 때, 혹은 정말로 확실한 경우에만 사용해야 한다.
let a: any = '덕배';
let b: number = (a as string).length; // 타입 캐스팅
// < > 연산자 사용
let b: number = (<string>a).length; // 타입 캐스팅
타입 단언과 타입 캐스팅은 둘 다 as 키워드와 <> 연산자를 사용할 수 있는데,
두 타입 다 as 키워드를 사용하면 코드가 동일해진다. 그러면 컴파일할때 타입 단언인지 타입 캐스팅인지 어떻게 알까?
=> 타입 단언과 타입 캐스팅은 구문적으로는 동일하게 표현되며, TypeScript에서는 이들을 구분하지는 않지만, TypeScript의 철학 중 하나는 자바스크립트와의 호환성을 지키면서 타입을 도입하는 것이므로 as 키워드를 사용한 부분을 타입 단언으로 해석한다.
그래서 자세히 보니, 타입 단언은 오직 컴파일타임에서만 타입을 변경시켜 런타임에 영향을 주지 않고, 타입 캐스팅은 컴파일타임과 런타임에서 모두 타입을 변경시킨다.