[React] React + TypeScript 기본

정수완·2024년 3월 27일
0

React

목록 보기
5/8
post-thumbnail

1. React + TypeScript 프로젝트 생성하기

React Docs 에 따라서 npx create-react-app my-app --template typescript 로 bash 창이나 cmd 창에서 실행 시키면 됩니다.


2. tsconfig.json 설정

React + TypeScript 프로젝트를 최초 생성하면 tsconfig.json 설정을 조금 수정해 주어야 합니다.

보시는 것처럼 target: "es5"lib: [] 설정이 있는데 각각 이부분에 es6 로 변경하고 추가해 주겠습니다.


3. 타입지정


타입 스크립트의 기본

let car:string = "bmw" // 타입 지정 해줘야 한다.
car = 3 // -> string 으로 타입 지정 했는데 3인 숫자 넣어서 오류

처럼 타입스크립트의 기본은 변수에 타입을 지정하는 것입니다.


타입추론

  • 타입을 지정하지 않고 뒤에 오는 인수의 형태를 보고 타입을 알아서 지정하는 형식으로 타입스크립트가 알아서 타입을 지정합니다.
let car = "bmw"

타입 지정없이 변수를 선언했을 때 위 코드의 car 의 타입은 string 이 됩니다.
변수를 선언하거나 초기화 할때 타입이 추론되고, 이외에도 변수, 속성, 인자의 기본 값, 함수의 반환 값 등을 설정할 때 타입의 추론이 발생합니다.

오류 발생을 대비해 기본적으로 모든 타입을 지정해 주는 것이 적절합니다.


형태별 타입형식

let age:number = 30;
let isAdult:boolean = true;

// 숫자배열
let a:number[] = [1,2,3]
let a2:Array<number> = [1,2,3]

// 문자배열
let week1:string[] = ["mon", "tue", "wed"]
let week2:Array<string> = ["mon", "tue", "wed"]

//튜플
leb b:[string, number];
b = ["z", 1] // 가능
b = [1, "z"] // 불가능

기본적인 타입 선언 방식이며, 배열의 경우 2가지 방식으로 선언이 가능합니다.
튜플의 경우 0번값과 1번값의 타입을 지정해 두었으니 다른 타입이 들어가면 error가 발생합니다.


void, never 타입

1. void 형식

  • 함수형 타입에서 반환하는 값이 없는 경우 즉 return 이 없어 반환값이 없는 경우의 함수를 void 타입으로 지정합니다.
function cons():void {
	console.log("123")
}

2. never 형식

  • 함수의 반환값이 항상 error 이거나, 함수가 종료되지 않고 무한반복 하는 함수를 never 타입으로 지정합니다.
function showError():never {
	throw new Error()
}

function infLoop():never {
	while (true) {
		// do something..
	}
}

enum 타입

쉽게 말하자면 비슷한 값들을 묶어준 타입이라 생각하시면 됩니다.

enum Direction {
  Up = 1,
  Down,
  Left,
  Right,
}

여기서 up 을 1로 초기화된 숫자로 선언해 주었습니다.
그 지점부터 Down, Left, Right 는 자동으로 증가된 값을 갖습니다.

즉 Direction.Up 은 1, Down 은 2, Left 는 3, Right 는 4 의 값을 가지게 됩니다.

다른경우로 처음부터 초기화 하지 않아도 됩니다.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

위 코드에서 up은 자동으로 0을 할당 받게 됩니다. 그 이후는 자동으로 증가된 값인 1,2,3 을 할당 받습니다.

마찬가지로 문자열 역시 enum 타입으로 지정이 가능합니다.

enum Os {
	window = "win",
	Ios = "ios",
	Android = "android"
}

이처럼 비슷한 형태로 묶인 경우 enum 타입을 사용하게 됩니다.

이종 열거형 (Heterogeneous enums)

숫자와 문자를 섞어서 사용할 수 있지만 굳이 그렇게 할 이유는 없습니다.

enum BooleanLikeHeterogeneousEnum {
  No = 0,
  Yes = "YES",
}
확실하게 JavaScript 런타임에서 장점을 취하려는 것이 아니라면, 이렇게 사용하지 않는 것을 권장합니다.

더욱 자세한 보기는 TypeScript Handbook 을 참조 하시면 됩니다.


null, undefined 타입

타입스크립트에서 nullundefined 역시 하나의 타입이자 값 입니다.

let a:null = null;
let b:undefined = undefined;

하지만 null 타입으로 설정한 변수에 null 이 아닌 다른 값이 할당되면 오류를 출력합니다.

이처럼 오류에 대해 엄격하게 출력하는 이유는 tsconfig.json 에 설정값 때문입니다.

"strictNullChecks": true, /* 엄격한 null 검사 사용 */


Interface 타입

  • 자바스크립트의 경우 object 에 담긴 property 를 뽑아 쓰는 경우 예를 들어 usernameage 가 담겨 온 경우 뽑아 쓰기 위해서는 user.name 으로 사용하면 되지만 타입스크립의 경우에는 그렇게 작성하면 에러가 날 수 있습니다. 이를 해결하기 위한 것이 Interface 타입입니다.
interface User {
	name: string,
	age: number,
}

let user:User = {
	name: "swan",
	age: 10
}

console.log(user.name)
console.log(user.age)

위와 같이 User 타입을 지정하고 해당 타입을 받아오는 인자에 넣어 형식을 맞춰 주어야 오류가 발생하지 않습니다.

Interface 의 옵셔널체이닝

Interface 타입에서 해당 타입을 사용하거나 사용하지 않는경우 ? 를 통해 오류를 방지할 수 있습니다.

interface User {
	name: string,
	age: number,
	gender? : string,
}

let user:User = {
	name: "swan",
	age: 10
}

user.gender = "male"

console.log(user.name)
console.log(user.age)
console.log(user.gender)

위 코드에서 User 타입에 gender 속성을 옵셔널체이닝 형식으로 지정하였습니다.
만약 옵셔널체이닝 없이 gender 속성에 string을 사용하였다면 let user:User 변수는 에러를 반환합니다.

또한 위 코드처럼 user 변수 선언 후 아래에 새롭게 user.gender 로 선언해 주어도 에러가 나지 않습니다.


함수에 옵셔널체이닝

function hello(name: string, age?:number):string {
	if (age !== undefined) {
		return `Hello, ${name}. You are ${age}.`
	} else {
		return `Hello, ${name}`	
	}
}

함수를 정의할 때에도 옵셔널 체이닝을 사용 가능합니다.

위 코드에서 nameage 를 인자로 넘겨받는데 옵셔널체이닝을 이용하여 age의 여부를 처리하였습니다.

만약 hello 함수가 실행될 때 age 가 들어오지 않는다면 ageundefined 타입으로 넘어오게 됩니다.

주의할 점

위 코드에서 옵셔널체이닝을 활용하여 필수 매개변수선택적 매개변수를 동시에 사용하는 함수를 작성하였습니다.
이때 선택적 매개변수를 함수의 앞에 정의한다면 에러를 반환합니다. 반드시 필수 매개변수를 앞쪽에 써주어야 합니다.

참고

함수의 넘겨받는 파라미터에 기본값을 설정한다면 옵셔널체이닝과 동일한 효과를 나타냅니다.

function hello(name="hello") {
	return `Hello, ${name}`
}

여기서 아래에 const result = hello() 형식으로 함수를 정의한 뒤 사용해 주어도 에러가 나지 않습니다.
hello() 함수에 name 값이 옵셔널체이닝 형태가 되었기 때문입니다.

const result2 = hello(name='hi') 형식으로 사용하여도 에러가 발생하지 않습니다.


readonly 타입

  • 타입지정시 Interface 나 type 정의에서 readonly 속성을 사용할 수 있습니다.
interface User {
	name: string,
	age: number,
	gender? : string,
	readonly birthyear: number
}

let user:User = {
	name: "swan",
	age: 10,
	birthyear = 2000,
}

user.gender = "male"
// 오류: 상수나 읽기 전용 속성은 대입(assignment) 표현식의 좌항이 될 수 없음
user.birthyear = 1999 // -> 이건 readonly 형식을 재정의 하는거라 에러난다.
		

console.log(user.name)
console.log(user.age)
console.log(user.gender)

여기서 birthyear을 읽기 전용 타입으로 지정해 주었습니다.
그 후 user 변수에서 birthyear2000 으로 지정해 주었습니다. 근데 아래에서 새로이 1999 로 정의한다면 에러를 반환합니다.


Interface - extends

interface Car {
	color: string,
	wheels: number,
	start(): void
}

Car 타입을 위 코드와 같이 정의 하였을 때

interface Benz extends Car {
	door: number;
	stop() : void
}

이렇게 extends 를 활용하여 Car 타입을 불러와 새로이 타입을 재정의 하였습니다.

이렇게 사용한다면 Car 타입에 정의한 color, wheels, start 를 사용 가능합니다.

interface Car {
	color: string,
	wheels: number,
	start(): void
}

interface Toy {
	name: string,
}

interface ToyCar extends Car, Toy {
	price: number,
}

또 이런식으로 여러개를 , 로 구분하여 사용 가능합니다.


0개의 댓글