➕ zerocho님 typescript all-in-one 강의를 듣고 정리한 내용입니다.
// pakage.json 생성 ( node 프로젝트의 설정들을 모아둔 파일 )
npm init -y
// typescript 설치
npm install typescript
// tsconfig.json 생성
npx tsc --init
// tsconfig.json에서 켜놔야하는 속성
"allowJs": true,
"strict": true,
// type 검사할때
npx tsc --noEmit
// ts -> js
npx tsc
타입스크립트는 자바스크립트의 변수, 매개변수, 리턴값에 타입을 붙이는 것이다! 타입을 지워도 자바스크립트가 실행이 되어야하기에 처음에 어떻게 타입을 읽어야할지 모르겠다면 먼저 자바스크립트를 찾고 하나씩 타입을 붙여보자! ( 지울 수 있는 부분이 타입 )
타입스크립트이 주 목적은 any를 없애기!
이때 타입은 대문자(Number) ❌, 소문자(number) ⭕
// 변수 : 타입 = 값
const a : number = 5;
const b : string = "hello";
const c : boolean = true;
const d : undefined = undefined;
const e : null = null;
const f : symbol = Symbol.for('abc'); // es2015 문법
const g : bigint = 1000000n;
const h : any = '123'; // 모든 타입이 다 되기에 절대 사용하지 말기!
// const에서 값이 변할일이 없기에 고정된 원시값을 타입으로 지정하기도 함
const i : true = true;
const j : 5 = 5;
// 함수
function add(x : number, y : number) : number { return x + y }
// 화살표함수
const add : (x : number, y : number) => number = (x, y) => x + y;
// 타입 애일리어스 사용
type Add = (x : number, y : number) => number;
const add : Add = (x, y) => x + y;
//interface 사용
interface Add(){
(x : number, y : number): number;
}
const add : Add = (x, y) => x + y;
// 객체
const obj : { lat : number, lon : number } = { lat : 37.5, lon : 127.5 };
// 배열
const arr : string[] = ['123', '456']
const arr2 : Array<number> = [123, 456] // generic 사용
const arr3 : [number, number, string] = [123, 456, '789'] // tuple : 길이가 고정된 배열
vs code는 자동적으로 tsc --noEmit
을 실행한다. 따라서 자동적으로 타입을 추론한다. 타입은 최대한 정확하게 하는 것이 중요하기 때문에:5
라고 추론되는 타입을 굳이 :string
으로 하는 것이 부정확한 것이기도 한다.
따라서 타입스크립트가 any 혹은 의도와 다른 타입으로 추론할때만 타입을 직접 지정해줘도 된다.
const a = '5'; // 👎
const a : stirng = '5'; // ✨
type,interfacee, generic, as는 js로 바꿀때 사라진다! 따라서 이 친구들 없이도 코드가 작동하는지 꼭 확인!
: 타입 // : number, : string 등등
type Add = (x : number, y : number) => number;
interface Add(){
(x : number, y : number): number;
}
Array<Sring>
let a = 123
a = "hello" as unknown as number // a = "hello"
// 타입
function add = (x : number, y : number) => number;
// 선언
function add(x,y){
return x+y;
}
[] 빈배열
만을 선언하면 아무 타입도 선언할 수 없는 never 타입이 오기에 꼭 타입 선언!
cosnt array = []; // 👎
const array :number[] = []; // 👍
| ( or )
!
를 사용하면 null이나 undefined가 아님을 보증하는 것! 하지만 비추! 안정성이 떨어진다😨
무조건 타입은 소문자!
type World = "world" | "hell";
const a : World = "world";
World에는 world 또는 hell 만 가능! -> 타입정교화
// rest
let arr: string[] = [];
let arr2: Array<string> = [];
function rest(a, ...args: string[]) {
console.log(a, arg) // 1, [2,3]
}
rest('1', '2' '3')
// tuple
const tuple: [string, number] = ['1', 1];
tuple[2] = 'hello'; // ❌
tuple.push('hello'); // ⭕ (타입스크립트는 바보라 이거 됌...)
enum : 여러개의 변수들을 하나의 그룹으로 묶고싶을때
// enum ( js로 변환했을때 사라짐 )
const enum EDirection {
Up, // default : 0
Down, // default : 1
Left, // default : 2
Right, // default : 3
}
EDirection.Up; // 0
// 객체 ( js로 변환했을때 남아있음 )
const ODirection = {
Up: 0,
Down: 1,
Left: 2,
Right: 3,
} as const; // 타입스크립트가 정확하게 타입 추론을 하도록 (readonly)
// enum을 파라미터로 사용
function walk(dir: EDirection) {}
// enum을 사용하지 않았을때 함수에 파라미터로 넣는 방법
type Direction = typeof ODirection[keyof typeof ODirection];
function run(dir: Direction) {}
walk(EDirection.Left); // walk(2)
run(ODirection.Right); // run(3)
// keyof : 객체에서 key값만 가져오고 싶을 때
// typeof : 값을 type으로 쓰고 싶을 때
const obj = { a : '123', b : 'hello', c : 'world' } as const;
type Key = keyof typeof obj; // key들만 다 가져옴
type Key = typeof obj[keyof typeof obj]; // value들만 다 가져옴
keyof obj // const obj :{ a : string, b : string, c : string}
keyof typeof obj // "a" | "b" | "c"
typeof obj[keyof typeof obj] // "123" | "hello" | "world"
// union -> 사용❌
function add(x: string | number, y: string | number): string | number {
return x + y
}
const result : string|number = add(1, 2) // ⭕
// result 는 3(number)이지만 string or number 의 타입을 갖게 되어 문제가 발생!😨
add('1', '2')
add(1, '2')
type A = {
a: string;
}
type B = {
b: string;
}
const aa: A | B = { a: 'hello', b: 'world' };
const bb: A & B = { a: 'hello', b: 'world' };
타입을 선언하는 다양항 방법
// Type Alias -> 간단한 것
type A = { a: string };
const a: A = { a: 'hello' };
// interface -> 객체지향, 라이브러리 ( 확장가능 )
interface B { a: string }
const b: B = { a: 'hello' };
type Animal = {breath : true};
type Mammal = Animal & {breed : true};
type Human = Mammal & {think : true};
interface A {
breath : true
}
interface B extends A{
breed : true
}
const me : Human = {breath : true, breed : true, think : true};
interface는 확장성이 높다. ( 기능을 계속 추가할 수 있음 )
➕ 변수명 지을 때 네이밍 룰
interface I
type T
enum E
또는 잘 안붙이기도함 ( 에디터에서 타입에 마우스 올리면 다 보임 )