[Typescript] 타스형! 스터디 1주차

woo·2022년 10월 6일
0

Typescript

목록 보기
1/13
post-thumbnail

➕ zerocho님 typescript all-in-one 강의를 듣고 정리한 내용입니다.

✔ 기본지식

  • 메인 룰: typescript는 최종적으로 javascript로 변환된다. 순전한 typescript 코드를 돌릴 수 있는 것은 deno이나 대중화되지가 않았음. 브라우저, 노드는 모두 js 파일을 실행한다.
  • typescript는 언어이자 컴파일러(tsc)이다. 컴파일러는 ts 코드를 js로 바꿔준다.
  • tsc는 tsconfig.json(tsc --init 시 생성)에 따라 ts 코드를 js(tsc 시 생성)로 바꿔준다. 인풋인 ts와 아웃풋인 js 모두에 영향을 끼치므로 tsconfig.json 설정을 반드시 봐야한다.
    단순히 타입 검사만 하고싶다면 tsc --noEmit 하면 된다.
  • 개인 의견: tsconfig.json에서 그냥 esModuleInterop: true, strict: true 두 개만 주로 켜놓는 편. strict: true가 핵심임.
  • ts 파일을 실행하는 게 아니라 결과물인 js를 실행해야 한다.
// 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

✔ 섹션1

타입스크립트는 변수, 매개변수, 리턴값에 타입붙이는 것!

타입스크립트는 자바스크립트의 변수, 매개변수, 리턴값에 타입을 붙이는 것이다! 타입을 지워도 자바스크립트가 실행이 되어야하기에 처음에 어떻게 타입을 읽어야할지 모르겠다면 먼저 자바스크립트를 찾고 하나씩 타입을 붙여보자! ( 지울 수 있는 부분이 타입 )

타입스크립트이 주 목적은 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'; // ✨

js 변환시 사라지는 부분을 파악하자

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타입과 느낌표(non-null assertion)

[] 빈배열만을 선언하면 아무 타입도 선언할 수 없는 never 타입이 오기에 꼭 타입 선언!

cosnt array = []; // 👎
const array :number[] = []; // 👍

| ( or )

!를 사용하면 null이나 undefined가 아님을 보증하는 것! 하지만 비추! 안정성이 떨어진다😨

원시 래퍼 타입, 템플릿 리터럴 타입, rest, 튜플

무조건 타입은 소문자!

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, keyof, typeof

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(|)과 intersection(&)

  • union : 또는 ( 여러개 중에 하나만 있어도 된다. )
  • intersection : 둘다 만족 ( 모든 속성이 다 있어야 한다. )
// 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' };

타입 애일리어스(정의, 선언)와 인터페이스 상속(extends)

타입을 선언하는 다양항 방법

//  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

또는 잘 안붙이기도함 ( 에디터에서 타입에 마우스 올리면 다 보임 )

타입을 집합으로 생각하자(좁은 타입과 넓은 타입)

  • 넓은 타입 (or , |) : 합집합
  • 좁은 타입 (and, &) : 교집합
  • any : 전체집합
  • never : 공집합
profile
🌱 매일 성장하는 개발자

0개의 댓글