# typescript
# hello TS world
npm init # node 초기화
npm i @types/node # 타입스크립트 설치
npm install typescript -g # 컴파일러 설치
# -g (글로벌 옵션) : 컴퓨터 모든곳에서 사용 가능
tsc -v # 버전 확인
1
2
3
4
5
2
3
4
5
src.index.ts
console.log("hello typescript");
const a: number = 5;
1
2
2
tsc src/index.ts # 컴파일
node src/index.js # 실행
1
2
2
# 컴파일과 실행을 한번에 tsx
npm i -g tsx
tsx -v
tsx src/index.ts
1
2
3
2
3
# tsconfig.json 파일 만들기
tsc --init
1
`tsconfig.json`
{
"compilerOptions": {
"target": "ESNext", // 변환되는 자바스크립트 버전
"module": "ESNext", // 변환되는 자바스크립트 코드가 사용할 모듈 시스템버전
"outDir": "dist", // 컴파일된 자바스크립트 폴뎌
"strict": false, // 엄격한 검사
"moduleDetection": "force", // 개별 모듈로 취급
"moduleResolution": "node",
"skipLibCheck": true,
},
"include": ["src"] // 폴더 안에 파일 컴파일
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 타입스크립트는 모든 파일을 전역 모듈로 본다 export{} 처럼 모듈 키워드를 쓰면 그때부터 독립된 모듈로 본다. 또는 tsconfig.json 파일에 moduleDetection : force 옵션을 준다.
npm install -D @types/node@20
1
# 타입스크립트 기본타입
# 원시타입
하나의 값만 저장하는 타입
: number = 타입 어노테이션
// number
let num1: number = 123;
let num2: number = -123;
let num3: number = 0.123;
let num4: number = -0.123;
let num5: number = Infinity;
let num6: number = -Infinity;
let num7: number = NaN;
// string
let str1: string = "hello";
let str2: string = "hello";
let str3: string = `hello`;
let str4: string = `hello ${num1}`;
// boolean
let bool1: boolean = true;
let bool2: boolean = false;
// null
let null1: null = null;
// undefined
let unde1: undefined = undefined;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
number 타입에 임시로 null 을 넣고 싶을때
null 타입이 아닌 변수에 null을 넣을 수 있다.
tsconfig.json
"strictNullChecks": false,
1
# 리터럴 타입
값 자체가 타입이 된다 타입으로 정의된 값 외에 다른 값은 들어갈 수 없다
// 리터럴 타입
// 리터럴 -> 값
let numA: 10 = 10;
let strA: "hello" = "hello";
1
2
3
4
5
2
3
4
5
# 배열
// 배열
let numArr: number[] = [1, 2, 3];
let strArr: string[] = ["hello", "im", "winterlood"];
let boolArr: Array<boolean> = [true, false, true]; // 제네릭
// 배열에 들어가는 요소들의 타입이 다양할 경우
let multiArr: (number | string)[] = [1, "hello"];
// 다차원 배열의 타입을 정의하는 방법
let doubleArr: number[][] = [
[1, 2, 3],
[4, 5],
];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 튜플
자바스크립트에는 없고 타입스크립트에만 제공 길이와 타입이 고정된 배열
let tup1: [number, number] = [1, 2];
let tup2: [number, string, boolean] = [1, "2", true];
const users: [string, number][] = [
["이정환", 1],
["이아무개", 2],
["김아무개", 3],
["박아무개", 4],
// [5, "최아무개"],
];
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 객체
- ? : 선택적 프로퍼티 optional property 있어도 되고 없어도 됨
- readonly : 수정 불가
let user: {
id?: number;
name: string;
} = {
id: 1,
name: "이정환",
};
let config: {
readonly apiKey: string;
} = {
apiKey: "MY API KEY",
};
// config.apiKey = "hacked";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 타입 별칭 (type alias)
타입을 변수처럼
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
let user: User = {
id: 1,
name: "이정환",
nickname: "winterlood",
birth: "1997.01.07",
bio: "안녕하세요",
location: "부천시",
};
function test() {
type User = string; // 함수 안에서 User 타입은 string 이 된다
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 인덱스 시그니처
type CountryCodes = {
[key: string]: string;
};
let countryCodes: CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk",
};
type CountryNumberCodes = {
[key: string]: number;
Korea: number; // Korea 프로퍼티가 반드시 있어야 한다
};
type CountryNumberCodes = {
[key: string]: number;
Korea: string; // 인덱스시그니처 타입과 반드시 일치해야 한다 오류발생
};
// let countryNumberAndStringCodes: CountryNumberCodes = {
// Korea: "ko",
// };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 열거형 타입 (Enum Type)
타입스크립트에서만 제공
enum Role {
ADMIN,
USER,
GUEST,
}
enum Language {
korean = "ko",
english = "en",
}
const user1 = {
name: "이정환",
role: Role.ADMIN, // 0 <- 관리자
language: Language.korean,
};
const user2 = {
name: "홍길동",
role: Role.USER, // 1 <- 일반 유저
language: Language.english,
};
const user3 = {
name: "아무개",
role: Role.GUEST, // 2 <- 게스트
};
console.log(user1, user2, user3);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Any
특정 변수의 타입을 확실히 모를때
let anyVar: any = 10;
let num: number = 10;
num = anyVar; // 가능 unkown 은 불가능
1
2
3
4
2
3
4
# Unknown
let unknownVar: unknown;
unknownVar = "";
unknownVar = 1;
unknownVar = () => {};
if (typeof unknownVar === "number") {
// 타입 정제
num = unknownVar;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# void
function func1(): string {
return "hello";
}
function func2(): void {
console.log("hello");
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# never
불가능한 타입 strictNullChecks : false 여도 값을 담을 수 없음. anytype 도 담을 수 없다 (void 타입은 담을 수 있다)
function func3(): never {
while (true) {}
}
function func4(): never {
throw new Error();
}
let anyVar: any;
let a: never;
// a = 1;
// a = {};
// a = "";
// a = undefined;
// a = null;
// a = anyVar;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 타입은 집합이다
** 밑에서 위로 변수 할당 가능 ** anytype은 다운캐스팅/업케스팅 무시 ** never 타입에는 anytype 들어가지 못한다
# 객체 타입의 호환성
type Animal = {
name: string;
color: string;
};
type Dog = {
name: string;
color: string;
breed: string;
};
let animal: Animal = {
name: "기린",
color: "yellow",
};
let dog: Dog = {
name: "돌돌이",
color: "brown",
breed: "진도",
};
animal = dog;
// dog = animal; 오류 발생
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
animal 은 dog의 슈퍼타입/ dog 는 animal 의 서브타입
# 초과 프로퍼티 검사
type Book = {
name: string;
price: number;
};
let book2: Book = {
name: "한 입 크기로 잘라먹는 리액트",
price: 33000,
// skill: "reactjs", skill 작성 불가
};
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 대수 타입
여러개의 타입을 합성해서 새롭게 만들어낸 타입
# union 타입 (합집합 타입)
let a: string | number | boolean;
a = 1;
a = "hello";
a = true;
let arr: (number | string | boolean)[] = [1, "hello", true];
1
2
3
4
5
6
2
3
4
5
6
type Dog = {
name: string;
color: string;
};
type Person = {
name: string;
language: string;
};
type Union1 = Dog | Person; // 타입 별칭으로도 union 타입을 만들 수 있다
let union1: Union1 = {
// Dog
name: "",
color: "",
};
let union2: Union1 = {
// Person
name: "",
language: "",
};
let union3: Union1 = {
// Dog | Person
name: "",
color: "",
language: "",
};
// 허용 안됨
// let union4: Union1 = {
// name: "",
// };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Intersection 타입 (교집합 타입)
let variable: number & string; // => never 타입 (불가능.. 공집합)
1
객체 타입에서 주로 많이 사용한다
type Dog = {
name: string;
color: string;
};
type Person = {
name: string;
language: string;
};
type Intersection = Dog & Person;
// 프로퍼티가 하나라도 빠지면 안된다 모든 프로퍼티를 포함하는 타입
let intersection1: Intersection = {
name: "",
color: "",
language: "",
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 타입 추론 (Type Inference)
타입이 정의되어 있지 않은 변수의 타입을 자동으로 추론
# any type의 진화
let d; // any
d = 10; // any
d.toFixed(); // number
d = "hello"; // any
d.toUpperCase(); // string
1
2
3
4
5
6
2
3
4
5
6
변수를 선언하기만 하면 암묵적인 any타입으로 지정됨. 암묵적인 any type은 진화가능.
# const
const num = 10; // const 는 넘버리터럴타입으로 추론됨
const str = "hello";
1
2
2
# 최적의 공통타입으로 추론해준다
let arr = [1, "string"]; // let arr: (string | number)[]
1
# 타입 단언 (Type Assertion)
실제로 타입을 바꾸는것은 아니다. 컴파일러에게 잠시 단언해서 오류를 피함
타입 단언의 규칙
- 값 as 단언 <- 단언식
- A as B
- A가 B의 슈퍼타입이거나
- A가 B의 서브타입이어야 함
type Person = {
name: string;
age: number;
};
let person = {} as Person;
person.name = "이정환";
person.age = 27;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
type Dog = {
name: string;
color: string;
};
let dog = {
name: "돌돌이",
color: "brown",
breed: "진도",
} as Dog;
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
let num1 = 10 as never;
let num2 = 10 as unknown;
let num3 = 10 as unknown as string; // 다중 단언 좋은 방법은 아니다
1
2
3
4
2
3
4
# const 단언
readonly 로 추론됨. 모든 프로퍼티를 readonly로 만들어준다
let num4 = 10 as const;
let cat = {
name: "야옹이", // readonly 로 추론됨
color: "yellow", // readonly 로 추론됨
} as const;
1
2
3
4
5
6
2
3
4
5
6
# Non null 단언
type Post = {
title: string;
author?: string;
};
let post: Post = {
title: "게시글1",
};
const len: number = post.author!.length; // ? => !
// ! : 이 값이 null 이거나 undefined이 아닐것이다 라고 단언
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11