📌 타입스크립트 세팅
빈 프로젝트에 아래의 명령어들을 입력하여 타입스크립트를 사용할 수 있게 합니다.
npm init -y
npm install typescript --save-dev
ts-node
ts-node를 사용하면 tsc 명령어로 컴파일시키지 않고 바로 실행이 가능합니다.
사용법
npm install ts-node
ts-node src/index.ts
루트 디렉토리에 tsconfig.json을 생성하여 아래의 코드를 입력합니다.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
},
"include": ["src/**/*"]
}
tsconfig.json 옵션들
files
타입스크립트로 변환할 파일의 경로를 미리 정의해 놓을 수 있습니다.
{
"files": ["app.ts", "./component/todos.ts"]
}
include
files처럼 파일을 개별 지정하지 않고, 변환할 폴더를 지정합니다.
{
"include": ["src/**/*"]
}
// 와일드 카드 패턴
// * : 해당 디렉토리의 모든 파일 검색
// ? : 해당 디렉토리 안에 파일의 이름 중 한 글자라도 맞으면 해당
// ** : 하위 디렉토리를 재귀적으로 접근(하위 디렉토리의 하위 디렉토리가 존재하는 경우 반복해서 접근)
exclude
include와는 반대로 변환하지않을 폴더를 지정합니다. 설정하지 않을 경우, node_modules와 같은 폴더를 제외합니다.
{
"exclude": ["node_modules"]
}
compilerOptions
- target: tsc가 최종적으로 컴파일할 때 사용할 문법입니다. es6로 설정하면 es6를 기반으로 컴파일됩니다.
- module: 무슨 import 문법을 쓸 것인지 정합니다. commonjs는 require로 변환시킵니다.
- allowJs: js 파일들을 ts에서 import해서 사용할 수 있는지 판단합니다.
- checkJs: js 파일에서도 에러를 체크할 지 판단합니다.
- removeComments: 컴파일 시 주석을 제거할 지 판단합니다.
그 외에도 엄청 많으니 한 번 찾아보시면 좋을 것 같습니다.
📌 타입스크립트 기본 타입
Number
const num: number = 7;
String
const str: string = 'Typescript';
Boolean
const isCheck: boolean = false;
Array
const arr: number[] = [1,2,3,4,5];
const arr: Array<number> = [1,2,3,4,5]; // 제네릭 사용
Tuple
튜플은 길이가 고정되어있고, 각 요소의 타입이 지정되어 있는 배열 형식을 말합니다.
정의하지 않은 타입이나 인덱스로 접근할 경우 오류가 발생합니다.
const arr: [string, number] = ['number', 7];
Enum
enum Animal {
Cat,
Dog,
Eagle,
Whale
}
const cat: Animal = Animal.Cat;
const cat: Animal = Animal[0]; // 인덱스로 접근 가능
// enum의 인덱스를 임의로 변경 가능
enum Animal {
Cat = 1,
Dog,
Eagle,
Whale
}
Any
단어 그대로 어느 것이든 올 수 있는 타입입니다.
const str: any = 'string';
const num: any = 7;
const arr: any = [1, 2, '3'];
Void
변수라면 undefined, null만 설정 가능하고, 함수라면 반환 값이 없어야 하는 타입입니다.
let unuseful: void = undefined;
function notUse(): void {
console.log('not use');
}
📌 타입스크립트 함수
기존 자바스크립트 함수 선언 방식에서 매개변수와 반환 값에 타입을 추가합니다.
function sum(a: number, b: number): number {
return a + b;
}
타입스크립트는 전달받는 인자들을 필수로 받아야 합니다. 따라서 매개변수를 설정했다면 undefined나 null이라도 넘겨줘야 합니다.
만약 선택적으로 인자를 전달하고 싶다면 ?을 이용하면 됩니다.
function sum(a: number, b?: number): number {
return a + b;
}
sum(1, 2) // 3
sum(1, 2, 3) // error
sum(1) // 에러 없음
default parameter는 기존 js문법과 동일합니다.
📌 Union 타입
union 타입은 or 연산자 ( || )와 같이 a 또는 b라는 뜻을 가진 타입입니다.
function print(text: number | string) {
if (typeof text === 'string') text.slice(0, 5);
return text;
}
function print(text: any) {
text.sli // text의 타입이 any로 추론되기 때문에 자동완성이 생기지 않습니다.
}
주의할 점
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
function askSomeone(someone: Developer | Person) {
console.log(someone.name);
}
유니온 타입을 이용해서 타입 설정을 하면 타입 간의 공통적인 요소에만 접근이 가능합니다.
만약 다른 요소에도 접근하고 싶다면 타입 가드를 사용해야 합니다.
function askSomeone(someone: Developer | Person) {
// in 연산자는 객체의 속성 이름과 함께 사용하여 해당 속성이 객체 내에 존재하는지 여부를 검사
if ('skill' in someone) {
console.log(someone.skill);
}
if ('age' in someone) {
console.log(someone.age);
}
}
📌 Intersection 타입
Intersection 타입은 둘 이상의 타입을 결합하여 새로운 타입을 만듭니다. & 연산자를 사용합니다.
const value: number & string & boolean;
이렇게 하면 value는 number, string, boolean 타입 모두를 받을 수 있습니다.
// interface 예시
interface Person {
name: string;
age: number;
}
interface Developer {
name: string;
skill: number;
}
type Gosu = Person & Developer;
// Gosu의 타입
// {
// name: string;
// age: number;
// skill: string;
// }
📌 인터페이스 (Interface)
타입스크립트에서 인터페이스는 변수, 함수, 클래스에 사용되며, 보통 타입 체크를 위해 사용합니다.
인터페이스를 작성할 때 첫 알파벳을 대문자로 작성합니다. 이는 네이밍 컨벤션입니다.
interface User {
name: stirng;
age: number;
}
// 정상
const user: User = {
name: "Kim",
age: 20
}
// 정상
const user: User = {
age: 20,
name: "Kim"
}
// 정의된 프로퍼티보다 적게 선언했기 때문에 에러
const user: User = {
name: "anna"
}
// 정의된 프로퍼티보다 많게 선언했기 때문에 에러
const user: User = {
name: "anna",
age: 20,
job: "developer"
}
? 연산자를 사용하여 선택적으로 프로퍼티 작성이 가능합니다.
interface User {
name: string;
age?: number;
}
const user: User = {
name: "kim"
}
읽기 전용
interface User {
readonly introduce: string; // 읽기 전용 속성
}
const user1: User = {
introduce: 'hi!'
}
user1.introduce = 'hello'; // 에러
// 읽기 전용 배열
const arr: ReadonlyArray<number> = [1,2,3];
arr.push(4); // 에러
arr.splice(0,1); // 에러
arr[1] = 10; // 에러
인터페이스는 함수의 타입을 정의할 때도 사용 가능합니다.
interface login {
(id: string, password: string): boolean;
}
const loginUser: login = (id, pw) => {
console.log('로그인 성공');
return true;
}
클래스에서도 인터페이스를 활용할 수 있습니다.
interface Calculator {
add(x: number, y: number): number;
substract(x: number, y: number): number;
}
class SimpleCalculator implements Calculator {
add(x: number, y:number) {
return x + y;
}
substract(x: number, y: number) {
return x - y;
}
}
SimpleCaculator 클래스는 Caculator 인터페이스를 사용하여 작성되었기 때문에, Caculator 인터페이스에 정의된 add, substract 메서드를 반드시 작성해야 합니다. 또한 클래스 내의 메서드의 매개변수 타입을 한번 더 명시해줘야 컴파일 에러가 발생하지 않습니다.
인터페이스 또한 클래스처럼 인터페이스를 상속받아 확장이 가능합니다.
interface Person {
name: string;
age: number;
}
interface Student extends Person {
language: string;
}
interface Developer extends Student {
job: string;
}
📌 열거형 (Enum)
자바스크립트에서는 지원하지 않지만, 타입스크립트에서는 숫자형, 문자형 열거형을 지원합니다.
열거형은 일반적으로 상수를 대신하여 사용됩니다.
열거형은 코드의 가독성을 높여주고, 오타 같은 실수를 방지할 수 있습니다.
숫자형 열거형 (Enum)
enum Color {
Red,
Green,
Blue,
}
enum Color {
Red = 1,
Green = 2,
Blue = 4,
}
기본적으로는 각 값이 0부터 시작하여 1씩 증가합니다. 하지만 수동으로도 지정이 가능합니다.
문자형 열거형 (Enum)
enum HttpMethod {
Get = "GET",
Post = "POST",
Put = "PUT",
Delete = "DELETE",
}
function makeRequest(url: string, method: HttpMethod) {
// ...
}
makeRequest("/api/data", HttpMethod.Post);
문자형 열거형은 항상 명확한 값이 나오기 때문에 읽기가 좋습니다.
리버스 매핑 (Reverse Mapping)
enum Enum {
A
}
let a = Enum.A;
let keyName = Enum[a];
하지만 리버스 매핑은 문자형 이넘에는 존재하지 않습니다.
참고