타입스크립트 올인원 - 1

hangkemiii·2022년 9월 19일
0
post-thumbnail
post-custom-banner

타입스크립트를 왜 사용해야 할까?

프로그래밍 언어를 배우는 이유는 실제로 사용하는 프로그램을 만들기 위해서이고, 실제로 사용하는 프로그램에서 에러가 발생하는 것은 문제가 된다. 자바스크립트 프로그램을 타입스크립트로 바꾸면 안정성이 늘어나고 에러가 덜 발생하게 된다. 다만, 타입스크립트가 자바스크립트의 모든 에러를 잡아주는 것은 아니고 실수를 줄여준다고 보면 된다.

타입스크립트는 자바스크립트보다 자유도가 떨어질 수 있다는 단점도 있지만, 실무에서는 자유도보다는 에러를 줄이는 것을 더 중시해야 한다.


기본 지식

메인 룰

TypeScript는 최종적으로 JavaScript로 변환된다.

  • TypeScript는 언어이자 컴파일러(tsc)이다. 컴파일러는 ts 코드를 js로 바꿔준다.

  • tsc는 tsconfig.json에 따라 ts 코드를 js로 바꿔준다. 인풋인 ts와 아웃풋인 js 모두에게 영향을 미치므로 tsconfig.json 설정을 반드시 확인해야 한다.

  • ts 코드를 js 코드로 바꾸는 것이 아니라 단순히 타입 검사만 하고 싶다면 tsc --noEmit 하면 된다.

  • ts 파일을 실행하는 것이 아니라 결과물인 js를 실행해야 한다.

  • VS Code나 WebStorm 같은 에디터가 필수이다.


ts 문법

기본적으로 자바스크립트의 변수, 속성, 매개변수, 리턴값에 타입이 붙은 것을 타입스크립트라고 생각하면 된다. 타입은 항상 소문자로 시작해야 한다.

const a: string = '5';
const b: number = 5;
const c: boolean = true;
const d: undefined = undefined;
const e: null = null;
const f: any = true;

const obj: { lat: number, lon: number } = { lat: 37.5, lon: 127.5 };

이때 any 타입은 아무 타입이나 적용이 되기 때문에, 타입스크립트가 아니라 자바스크립트로 인식이 되는것과 마찬가지이다. 그렇기 때문에 any를 최대한 쓰지 않는 것을 목표로 해야 한다.

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;

함수의 경우에는 매개변수 뒤에 리턴값 타입을 선언해주며, 화살표 함수 역시 같은 방법으로 타이핑할 수 있지만, type을 별도로 분리해주어 선언할 경우 더 가독성이 좋은 코드를 작성할 수 있다. 타입스크립트는 타입을 지웠을 때 자바스크립트 코드가 나와야 하는 연습을 해야 한다.

interface Add {
  (x: number, y: number): number
}

const add: Add = (x, y) => x + y;

interface 역시 타입을 선언해주는 방법 중에 하나이다.

const arr: string[] = ['123', '456'];
const arr2: Array<number> = [123, 456];
const arr3: [number, number, string] = [123, 456, '789'];

배열은 위와 같은 방법으로 타입을 지정해주며, arr2는 제네릭 타입, arr3은 tuple로 배열의 길이가 고정된 타입이다.

const f: true = true;
const g: 5 = 5;

위와 같은 고정된 원시값을 타입을 아예 지정해줄 수도 있다.

let aa = 123;
aa = 'hello' as unknown as number;

타입스크립트에서는 시스템이 추론 및 분석한 타입 내용을 변환해줄 수도 있다. 이때 "타입 표명(type assertion)"이라 불리는 매커니즘이 사용되는데, TypeScript의 타입 표명은 프로그래머가 컴파일러에게 타입에 더 잘 알고 있다는 가정하에 사용된다.

타입스크립트는 자바스크립트보다 자유도가 낮아진다는 단점이 있지만, 실무에서도 타입을 갑자기 변환해주는 일은 거의 없기 때문에 자유도 측면에서 단점이라고 여길 수 없다.

try {
  const array = [];
  array[0];
} catch(error) {
  error;
}

타입스크립트에서 빈 배열은 never라는 타입으로 지정된다. 타입스크립트에서 never 타입은 값의 공집합이다. 집합에 어떤 값도 없기 때문에, never 타입은 any 타입의 값을 포함해 어떤 값도 가질 수 없다.

숫자 체계에 아무것도 없는 양을 나타내는 0처럼 문자 체계에도 불가능을 나타내는 타입이 필요하다.

"불가능"이라는 단어 자체는 모호하다. 타입스크립트에서는 "불가능"을 아래와 같이 다양한 방법으로 나타내고 있다.

  • 값을 포함할 수 없는 빈 타입

  • 제네릭과 함수에서 허용되지 않는 매개변수

  • 호환되지 않는 타입들의 교차 타입

  • 빈 합집합(무의 합집합)

  • 실행이 끝날 때 호출자에게 제어를 반환하지 않는 함수의 반환 타입

  • 절대로 도달할수 없을 esle 분기의 조건 타입

  • 거부된 프로미스에서 처리된 값의 타입

const head = document.querySelector('#head')!;
console.log(head);

const head = document.querySelector('#head');
if (head) {
  console.log(head);
}

타입스크립트에서 !는 Definite Assignment Assertions으로 해당 변수의 타입을 확신할 경우에 붙여줄 수 있다. 하지만, 타입이 변할 수도 있고 타입을 확신하는 것은 에러가 발생할 수 있기 때문에 사용을 지양하고 if문을 사용하는 편이 좋다.

type World = "world" | "hell";
const a: World = 'world';

const b: `hello ${a}`;

//type Greeting = 'hello world'
type Greeting = `hello ${World}`;
const c: Greeting = 'hell'
const enum EDirection {
  Up,
  Down,
  Left,
  Right,
}

const a = EDirection.Up // 0
const b = EDirection.Left // 2

enum은 열거형 변수로 정수를 하나로 합칠 때 편리한 기능이다. 임의의 숫자나 문자열을 할당할 수 있으며 하나의 유형으로 사용해서 버그를 줄일 수 있다.

type A = { a: string };
const a: A = { a: 'hello' };

interface B { a: string };
const b: B = { a: 'hello' };

간단한 타입을 지정하고 싶을 때는 type, 객체지향형 프로그래밍을 구현하고 싶을 때는 interface를 사용하는 편이 좋다.

function add(x: string | number, y: string | number): string | number { return x + y }
// union, 여러 속성 중 하나만 있어도 된다.
const result: string | number = add(1, 2);
result.charAt()
add('1', '2')
add(1, '2')

type A = { hello: 'world' } & { name: 'kyeom' };
// intersection, 모든 속성이 다 있어야 한다.
const a: A = { hello: 'world', name: 'kyeom' };
type Animal = { breath: true };
type Mammal = Animal & { breed: true };
type Human = Mammal & { think: true };

const Kyeom: Human = { breath: true, breed: true, think: true };

|는 Union이라 부르며, 또는 관계이기 때문에 타입을 여러개 넣을 수 있다. 그러나 타입스크립트는 모든 경우의 수를 고려하기 때문에, 타입 추론이 잘 되지 않는다는 단점이 있다. 타입스크립트를 사용할 때에는 처음 타입을 제대로 선언하지 않으면 이후의 모든 코드가 에러가 발생할 위험이 있다.

&는 여러개의 타입이 모두 만족할때에 사용한다. 보통 객체에 사용하며, 객체의 모든 속성이 타입과 같아야 한다. 상속의 개념으로 생각하면 편하다.

interface A {
  talk: () => void;
}
interface A {
  eat: () => void;
}
interface A {
  laugh: () => void;
}

const a: A = { talk() {}, eat() {}, shit() {} }

interface는 여러번 선언할 수 있으며, 선언할 때마다 합쳐지게 된다. 라이브러리들은 대다수가 interface로 선언되어 있으며, 사용자가 추가적으로 수정할 수 있다. void는 자바스크립트에 없는 키워드로, 함수에 해당 함수가 아무것도 반환하지 않는다는 것을 명시해주는 타입이다.

profile
Front-End Developer
post-custom-banner

0개의 댓글