주제: TypeScript

리액트와 웹팩, 바벨

웹팩

  • 모듈 번들러입니다.
  • 모듈은 하나의 파일이고, 번들은 여러 파일을 합쳐서 하나의 파일을 만들어 준 결과 파일입니다.
  • 번들러는 번들을 해 줍니다.
  • 리엑트 개발을 할 때 수 많은 파일이 어디에서 시작되는지 신경쓰지 않고 서로 import하며 개발을 할 수 있게 해주는 것이 웹팩입니다.
  • 원래 JS에서 코드를 작성할 때 순서가 가장 중요했는데 웹팩 덕분에 상

바벨

  • 컴파일러입니다.
  • 컴파일러는 사람이 이해하기 쉬운 고수준 언어를 기계가 이해하기 쉬운 저수준의 언어로 바꿔주는 것을 이야기합니다.
  • 바벨은 JS → JS로 컴파일해주는데 ES6를 다른 버전(ES5)로 바꿔주는 역할을 합니다. 따라서 구버전의 브라우저에서도 최신의 JS문법을 이해할 수 있도록 바꿔주는 것입니다.
  • CRA, NEXT.js로 타입스크립트를 사용하면 컴파일러가 세팅되어 있기 때문에 개발자가 따로 세팅할 것은 없습니다.
  • JSX도 JavaScript로 바꿔주는 역할을 하는 게 바벨입니다.

TypeScript의 특징과 장단점

특징

  • 타입스크립트는 마이크로소프트가 개발한 타입이 추가된 언어입니다.

장점

  • 개발 단계에서 런타임 전에 에러를 잡고 문법 오류를 찾아낼 수 있어서 개발 속도가 빨라집니다.
  • 협업과 유지보수할 때도 바로 타입을 체크할 수 있으니까 코드만 가지고도 정확한 개발을 할 수 있습니다.

단점

  • 타입이 엄격하기 때문에 자바스크립트의 타입 유연성 장점이 사라집니다.
  • 타입 선언 때문에 오히려 생산성이 떨어질 수도 있습니다.

스크립트 언어와 컴파일 언어의 차이

  • 타입스크립트는 자바스크립트로 컴파일이 필요한 컴파일 언어입니다.
  • 컴파일을 하면서 미리 오류를 잡아낼 수 있습니다.
  • 사용자와 직접 만나기 전에 에러를 잡아낼 수 있으니 생산성이 높아집니다.

자바스크립트에 없는 타입

any - 아무거나 타입 입력 가능 (이거 쓰면 자바스크립트랑 다른 것이 없습니다.)

void - 함수의 return이 없을 때 사용합니다.

enum - 정해진 값의 세트를 사용할 때 사용합니다. (상수 세트 값 필요할 때)

export enum AssignmentStatus {
  Submitted,
  Pending,
  Rejected,
  Passed
}

union - 여러 타입이 올 수 있을 때 사용합니다.

function formatDate(date: string | number | Date): string {
	// 로직 생략

	return `${year}년 ${month}월 ${day}일`
}

formatDate(20201028);
formatDate(new Date());
formatDate('20201028');

tuple

let starArr: [number, string]= [1, '1점'];

Type 별칭 (Type Alias) - 타입을 직접 만들어서 사용합니다.

type ID = number | string;

function checkInfo(info: { id: ID; pw: string }) {

}

let id: ID = "1010";
checkInfo({ id, pw: "password" });

타입추론 (Type Inference)

  • 타입스크립트는 타입을 표기하지 않아도 컴파일러가 할당된 값을 보고 타입을 추축한다는 특징이 있습니다. (일반 정적타입언어와 다른 점입니다.)
  • 정말 타입이 필요가 없을 때 타입 쓰는 것을 생략하는 경우도 있습니다.
let starArr = [1, 2, 3];
starArr.push('4점');  // 에러: Argument of type 'string' is not assignable to parameter of type 'number'.

인터페이스 (Interface)

  • 객체의 타입을 정의할 때 많이 쓰입니다.

객체 타입 정의

  1. 바로 타입을 정의하는 방법
function getInfo(restaurant: **{ name: string }**) {
	console.log(restaurant.name);
}

  1. 인터페이스 ( 2개 이상)
interface Restaurant {
	name: string;
	star: 5;
}

function getInfo(restaurant: Restaurant) {
	console.log(restaurant.name);
}

const chroad3 = {
	name: "취향로3가",
	star: 5
};

getInfo(chroad3);
  • 아래와 같이 예정되지 않은 프로퍼티를 추가하면 에러가 납니다.
interface Restaurant {
	name: string;
	star: number;
}

const chroad3: Restaurant = {
	name: "취향로3가",
	star: 5,
	address: "을지로3가",
};
  • 그런데 타입 추론을 통해서 아래 코드는 에러가 안 납니다.
interface Restaurant {
	name: string;
	star: number;
}

const chroad3Value = {
	name: "취향로3가",
	star: 5,
	address: "을지로3가",
};

const chroad3: Restaurant = chroad3Value;

다양한 프로퍼티 타입

  • 객체의 프로퍼티 타입을 다양하게 사용할 수 있습니다.

인터페이스 확장

  • extends 키워드를 사용해서 인터페이스를 확장할 수 있습니다.
interface BasicInfo {
	name: string;
	star: number;
}

interface DetailInfo extends BasicInfo {
	address: string;
	phone: string;
	position: number[];
}

교차 타입(Intersection Types) 활용

  • &기호를 사용해서 기종 정의했던 인터페이스를 합쳐서 새로운 타입을 만드는 것입니다.
  • 이때는 interface를 쓸 수 없습니다.
  • type으로 만들어야 합니다.
interface BasicInfo {
	name: string;
	star: number;
}

interface DetailInfo {
	position: number[];
}

**type** Info = BasicInfo & DetailInfo;
  • Info타입은 position, name, star 전부 다 필요합니다.

타입호환성 (Type Compatibility)

interface Restaurant {
	name: string;
	star: number;
}

let **chroad3**: Restaurant;  // chroad3 변수 선언

let chroad3withAddress = {   // chroad3withAddress 변수 선언하고 초기화
	name: "십분의일",
	star: 5,
	address: "을지로3가",
};

chroad3 = chroad3withAddress;
  • 위 코드는 에러가 나지 않습니다. 왜냐하면 chroad3withAddress가 타입을 초기화했기 때문입니다.
  • 이렇게 호환되기 위한 조건은 오른쪽에 있는 타입이 왼쪽을 포함해야 합니다.
function getStar(score: number | string, scoreNum: number) {
	const v1: number = score;
	const v2: number | string = scoreNum;
}
  • v1은 score에 string을 넣은 것이 오면 타입이 string으로 되어서 에러가 날 것입니다.

제네릭 (Generic)

  • <>을 사용하면서 유동적으로 타입이 정의됩니다.
  • 고정된 타입이 아니고 내가 원하는 타입을 자유롭게 지정해서 사용하고 싶을 때 사용합니다.
function makeArr<T>(el: T): T[] {
	return [el];
}

makeArr<number>(1);      // 1
makeArr<string>("1점");  // 2
makeArr<boolean>(true);  // 3
  • <>에 number를 넣으면 T는 넘버가 됩니다.
  • <>에 string을 넣으면 T는 string이 됩니다.
  • <>boolean을 넣으면 T는 boolean이 됩니다.
makeArr(1);
makeArr("1점");
makeArr(true);
  • 위처럼 넣어도 되지만 타입을 넣는 연습을 합시다.
  • 유지 보수가 힘들어질 것입니다.

리엑트를 위한 타입스크립트

Type보다는 Interface!

공식 문서에서 Inteface를 쓰라고 나와 있습니다. type을 써도 되지만 공식 문서에 따르는 것이 좋을 것 같습니다.

Type과 Interface 차이

  • type은 정의를 볼 때 모든 프로퍼티가 다 나옵니다. (vscode에서)
  • inteface는 inteface이름만 간결하게 나옵니다.

리엑트의 FC 타입 사용

  • React.FC를 쓰거나
  • input, output 타입을 정하거나 하면 됩니다.
**interface StarsProps {**  // prop 타입 정의
	star: number;
}

const Stars: React.**FC<StarsProps>** = ({ star }) => {   // 2
	// 로직

	return ( 
		<div>
			{makeStars(star)}
		</div>
	)
}

Hooks

  • useState
  • 제네릭으로 타입을 넣습니다.
const [like, setLike] = useState<boolean | null>(null);
//유니온으로 초기 null 값도 넣을 수 있습니다.

useRef

  • 코드의 명확성을 위해 타입을 정의하고 싶은 경우는 ref의 태그에 맞는 제네릭을 넘겨주면 됩니다.
const reviewRef = useRef<HTMLDivElement>(null);
  • HTMLAnchorElement, HTMLButtonElement, HTMLTableElement 등이 있습니다.

이벤트 핸들러

const updateValue = (e: React.ChangeEvent<HTMLInputElement>) => { // 1
	setEmail(e.target.value);
};
  • 타입 이름은 ‘이벤트타입Event’로 쓰면 됩니다. (ChangeEvent, FormEvent, TouchEvent, FocusEvent, KeyboardEvent, MouseEvent, DragEvent)

기타

JSX.Element

  • 변수에 JSX를 할당해서 값을 사용하는 경우 아래와 같이 선언합니다.
const WarningText: JSX.Element = <p>다시 확인해주세요.</p>

전역 변수

  • window에 외부 라이브러리 변수를 추가하려면 라이브러리에서 사용하는 전역 변수명을 추가하면 됩니다.
declare global {
	interface Window {
		kakao: any;
	}
}
  • 카카오 지도, 로그인 라이브러리 추가할 때 window.kakao로 접근하면 됩니다.

♧ 이 내용은 원티드, 위코드 프리온보딩 코스 강의를 들으면서 정리한 내용입니다.

Last modified: 2022년 02월 13일

Comments

Write a Reply or Comment

Your email address will not be published.