JS
는 동적인 타입을 지원하기 때문에 예상하지 못한 이슈가 생겨TS
로 미리 정적인 타입을 지정해주기 때문에 에러 확률이 현저히 낮아진다.TS
는 JS
보다 에러 메세지가 정확하게 나온다.
- JS(동적 언어)는 런타임에 타입 결정하고 오류를 발견한다.
- TS(정적 언어)는 컴파일 타임에 타입 결정하고 오류를 발견한다.
높은 수준의 코드 탐색과 디버깅
자바스크립트 호환
강력한 생태계
점진적 전환 가능
프로젝트의 규모가 크고 복잡할수록, 유지보수가 중요한 장기 프로젝트일수록 타입스크립트의 이점이 부각된다.
$ npm i -g typescript
.ts
확장자로 파일 생성tsconfig.json
: ts 컴파일 설정{
"compilerOptions" : {
"target": "es6",
"module": "esnext",
"strict": true,
}
}
$ tsc -w
// 문자열 타입 지정
let firstName :string = 'chul-su';
// 배열 타입 지정
let lastName :string[] = ['kim', 'lee']; // 배열 요소는 문자열만 가능하게 타입 지정
// 객체 타입 지정
let fullName :{ firstName: string, lastName?: string } // lastName 키 값은 옵션
= { firstName: 'chul-su', lastName: 'kim' } // 객체 요소 타입 지정
// 다양한 타입 지정가능 => Union type
let random :string[] | number = 123;
// 타입을 변수에 담아쓸 수 있음 => Type alias
type MyType = string[] | number;
let random :MyType = 123;
// 함수 파리미터, 리턴 타입 지정 가능
const myFunction = (x :number) :number => {
return x * 2;
}
// 배열의 tuple 타입 => 배열의 요소별로 타입 지정 가능
type Member = [number, boolean];
let john :Member = [123, true];
// 객체에 타입 지정할 속성이 많을 때
type Member = {
[key :string] : string // 키가 문자열이면 키값도 문자열 타입 지정
};
let john :Member = {key: 'keyValue'};
// class 타입 지정 가능
class User {
name :string;
constructor(name :string) {
this.name = name;
}
}
<h4 id='title'>안녕하세요</h4>
<a class='link' href='naver.com'>링크</a>
<button id='button'>버튼</button>
const title = document.querySelector('#title');
// title이 null일 수 있기 때문에 narrowing (Untion type) 5가지 방법
// 1. 비교 연산자
if (title !== null) title.textcontent = 'hi';
// 2. instaceof 연산자
if (title instaceof Element) title.textcontent = 'hi';
// 3. as 키워드 (되도록 지양)
const title = document.querySelector('#title') as Element;
title.textcontent = 'hi';
// 4. ?. 연산자 (optional chaining)
// title에 textcontent가 있으면 출력, 없으면 undefined 출력
if (title?.textcontent) title.textcontent = 'hi';
if (title?.textcontent !== undefined) title.textcontent = 'hi';
// a태그 narrowing
const link = document.querySelector('.link');
if (link instaceof HTMLAnchorElement) link.href = 'https://kakao.com';
/*
Element 타입
=> 태그마다 Element 타입이 정해져 있음
1. HTMLAnchorElement
2. HTMLHeadingElement
3. HTMLButtonElement
*/
// button narrowing
const button = document.querySelector('#button');
// 1.
if (button instaceof HTMLButtonElement) {
button.addEventListner('click', () => {});
}
// 2.
button?.addEventListner('click', () => {});
Interface
는 변수에 타입을 지정해서 담을 수 있다.Class
는 Interface가 컴파일된 JS에 안 보이기 때문에 대신에 OOP형식으로 사용type Score = 'A' | 'B' | 'C' | 'D' | 'F';
interface User {
name: string;
age: number;
gender?: string; // ?: optional
readonly birthYear: number; // readonly: 읽기 전용
[grade: number]: Score; // 키와 키값 타입 지정
};
let user: User = {
name: 'hoony',
age: 30,
birthYear: 1993,
1: 'D',
2: 'B'
}
interface Add {
(num1: number, num2: number): number;
}
const add: Add = (x, y) => x + y;
interface IsAdult {
(age: number): boolean;
}
const isAdult: IsAdult = age => age > 19;
interface Car {
color: string;
wheels: number;
start(): void;
}
interface Toy {
name: string;
}
// extends 두개 확장
interface ToyCar extends Car, Toy {
price: number;
}
// extends
interface Benz extends Car {
door: number;
stop(): void;
}
const benz: Benz = {
color: 'black',
wheels: 4,
door: 5,
start() {
console.log('Go start');
},
stop() {
console.log('Stop!');
}
}
// implements
class Bmw implements Car {
color;
wheels = 4;
constructor(color: string) {
this.color = color;
}
start() {
console.log('Go start');
}
}