타입스크립트 기초(타입스크립트 소개와 배경~제네릭) 정리

왜 typescript를 사용할까?

  1. type 에러를 정적시간에(사전에) 모두 잡아내어 생산성 및 코드 안정성을 향상
    (+ 또한, 서비스의 크기가 큰 경우 이런 에러를 typescript 도움없이 잡아내기도 쉽지 않다.)
  • 최소한 type으로 인한 에러는 막아준다. ⇒ 생산성 향상 ⇒ 어떻게? 에러의 원인을 찾는데 드는 시간 절약! 코드를 실행시켜야 발견할 수 있는 에러들을 정적인 시간에 발견하고 처리가능
  • ex) 잘못된 속성에 접근할 때, 특정한 타입에 대한 메소드가 없는데 사용할 때...
  1. 코드 가이드(요구되는 파라미터 및 예상 반환 타입)
  2. 타입에 따른 API(메소드) 자동 완성
  • 미리 타입을 정의해놓으면 코드 가이드에 따라 사용하기 편함. (생산성 향상) → 받은 값에 어떤 속성이 있는지 브라우저에서 확인하거나 또는 문서를 확인할 필요가 줄어듦.

근데 javascript로 typescript를 흉내낼 수 있다는데???

  • js doc, import ts-check
// @ts-check

/**
 * @typedef {object} Address
 * @property {string} street
 * @property {string} city
 */

/**
 * @typedef {object} User
 * @property {string} name
 * @property {string} email
 * @property {Address} address
 */
  • 하지만, type을 재활용 및 확장을 편하게 할 수 있고,
  • 코드량 줄고 가독성이 더 높은 방법은 typescript이다.

함수 정의

function gretting (name: string): string {
	return `${name}님 안녕하세요`
}

// 함수 타입 정의
interface APIFunc {
	(url: string): Promise<Response>;
}

const LoginAPI: APIFunc = (url: string): Promise<Response> => {
	return await fetch(url);
}

인덱싱 방식 정의 / 딕셔너리 패턴

interface MyStringArray {
	[index: number]: string; // index: value
}

interface MyDict {
	[key: number]: RegExp; // key: value
}
// => 원하는 타입의 key, value를 가진 item만 삽입 가능.

확장

interface Person {
	id: number,
	name: string
}

interface Developer extends Person {
	language: string
}

const hyeon: Developer = { id: 4, name: '현정', language: 'js' };
// Developer 및 Person의 모든 속성 다 갖고 있어여함

타입 별칭

type은 타입의 참조값을 갖는다. 새로운 타입을 만들어내는 interface와 다르다.
type으로는 타입을 확장하지 못한다. 그래서 type과 interface의 가장 큰 차이는 확장 가능 여부이다.

type MyType = string | number;

유니온과 인터섹션

type MyType = string | number;

function myFunc (value: MyType) {
  // 두 타입의 공통된 속성에 접근 가능 / 인터섹션 사용 시 합집합에 속하는 속성들에 접근 가능
	if (typeof value === 'string') {
		value. // string이 가진 속성 자동 완성
	} else {
	 // number이 가진 속성 자동 완성
	}
}

이넘

특정한 값의 집합을 사용할 때 사용 가능하다.
기본적으로 각 원소에는 실제 정수값이 0부터 할당된다.
명시적으로 숫자 또는 문자 값을 할당할 수 있다.

enum Answer {
	YES = 'Y';
	NO = 'N';
}

function check (answer: Answer) {
	if (answer === Answer.YES) {
	 
	}
}

check(Answer.YES);
check(Answer.NO);
check('Yes'); // error!

클래스

js에서 사용할 수 있는 개념이기도 하나, 사용법이 약간 다르다.

  1. 속성이 미리 정의 되어있어야 함
  2. private/public/readonly 키워드를 사용할 수 있음

제네릭

java, c++ 등 다른 언어에서의 제네릭과 동일한 의미(사용하는 시점에 타입을 지정)를 가진다.
함수 또는 인터페이스 등에 제네릭을 활용할 수 있다.

  • 타입별로 만든 함수에서 중복된 코드를 발견할 수 있는데, 제네릭을 사용해서 개선할 수 있다.
function logText<T> (text: T): T {
	console.log(text);
	return text;
}

logText('제네릭을 사용하면 반환값의 타입에 대한 api가 자동완성돼요!');
  • 이를 유니온 타입을 이용해서 구현하게 되면, 반환값의 타입은 항상 유니온 타입이어서 api 자동완성 기능의 도움을 받지 못함. → 제네릭을 사용하면 됨.
  • 인터페이스에서 사용하게 되면, 속성의 타입만 약간씩 다른 타입들을 제네릭을 적용해 하나의 타입으로 묶을 수 있음.

제네릭에서의 타입 제한

그냥 제네릭을 사용하면 모든 타입들이 들어갈 수 있다. (string, number, Person...)
타입 제한을 적용해서 개선가능하다.

  1. 힌트 주기
function printArray (array: T[]) {
	array.length; // 기본적으로 배열에서 제공하는 api에 접근 가능
}
  1. 정의된 타입 사용하기

T extends [type] 사용 시, type의 속성을 가지고 있는 타입들만 사용하도록 제한할 수 있다.
그 밖의 타입의 값들 사용시 에러가 발생한다.

좋은 웹페이지 즐겨찾기