[Code Camp_TIL] 230324 DAY10

23·2023년 4월 9일
0

FrontEnd TIL

목록 보기
10/13
post-thumbnail

🎯 수업 목차

  1. 타입스크립트
  2. 타입스크립트를 사용하는 이유
  3. 타입스크립트 확장자와 추론
  4. 유틸리티 타입
  5. API 응답 데이터의 타입

👩🏻‍💻 오늘의 TIL

타입스크립트

타입스크립트란 자바스크립트의 타입을 강제시키는 언어이다!
기존의 자바스크립트에서는 변수에 문자열을 할당했다가 이후에 숫자열을 재할당 하더라도 문제가 발생하지 않는다.

// 자바스크립트는 자료형에 연연하지 않고 할당이 가능하다.
let hello = "hello"
hello = 12345

하지만 타입스크립트에서는 변수의 자료형을 지정해주기 때문에 다른 타입의 재할당이 불가능하다.

let hello:string = "hello" 

// ❌ 불가능
hello = 12345
// ⭕️ 문자열만 할당 가능하다!
hello = "12345"

❗️브라우저는 HTML,CSS,Javascript만 읽을 수 있는데 타입스크립트는 어떻게 읽을까?

👉 실행될 때 자바스크립트로 변경되어 실행된다!
이렇게 변경되는 작업을 **컴파일 또는 트랜스파일** 이라고 합니다.
이렇게 변경해주는 도구를 **컴파일러 또는 트랜스파일러** 라고 합니다.

컴파일: 하나의 언어가 다른 언어로 변경되는 작업

트랜스파일: 하나의 언어가 같은 언어의 다른 버전으로 변경되는 작업


타입스크립트를 사용하는 이유

자바스크립트는 타입을 엄격하게 처리하지 않는다.
따라서 변수나 상수를 만들어 처음에는 문자를 넣었다가 나중에 숫자를 넣는 등 자유롭게 변환이 가능하다.
이러한 점이 개발에는 굉장히 편리해 보이지만, 큰 서비스를 여러 명이 개발하는 경우에는 문제가 될 수 있다.

❗️ 타입스크립트를 사용하지 않으면 발생할 수 있는 문제

  • 숫자만 입력 가능한 데이터에 문자열을 더해 데이터가 문자열로 변경되는 실수 등
    '0'(문자열) + 1 + 1 + 1 + 1 + 1
    (= 결과: '011111')
    따라서 실무에서 타입을 강제하는 것이 굉장히 중요하다.

타입스크립트는 타입을 지정하여 숫자열 변수에는 숫자열만 할당할 수 있고, 문자열 변수에는 문자열만 할당할 수 있도록 하여 안정성을 높여준다.

타입스크립트 사용 방법

// 변수명 뒤에 타입을 지정해주시면 된다.
let aaa : string = "안녕하세요"
let bbb : number = 123

객체 타입을 만들어줄 때는 네이밍 관례가 있다.

interface를 이용하여 객체의 value값의 타입을 지정해줄 수 있다.
이때, interface의 I와 변수명을 합쳐주는 것이 관례이다.
예를 들어 객체를 담은 변수 이름이 profile이라면 타입은 IProfile로 네이밍해줄 수 있다.

// 객체의 타입 지정
interface IProfile {
    name: string;
    age: number | string;
    school: string;
    hobby?: string;
  }
const porfile: IProfile = {
    name: "철수",
    age: 8,
    school: "다람쥐 초등학교",
  };

타입스크립트를 이용해 각 변수에 타입을 지정해주면, 타입에 맞지 않는 값을 할당 시 에러가 나게 된다!!

타입스크립트 파일 확장자와 타입 추론

return을 포함하고 있는 타입스크립트 파일의 확장자를 .ts로 설정하면 오류가 발생한다.
이는 return 부분이 사실 JSX, 즉 자바스크립트 XML이기 때문이다.
따라서 단순히 javascript만 있는 .js 파일은 typescript의 .ts로 변경하고 JSX를 return하는 컴포넌트들은 typescript의 .tsx로 변경하여야 한다.

💡 타입스크립트 확장자

  1. JSX를 return 하는 컴포넌트 : .tsx
  2. 자바스크립트만 사용하는 컴포넌트 : .ts

타입 추론

ts 혹은 tsx 파일은 변수에 타입을 따로 정의하지 않고 할당을 하게 되면 타입스크립트는 할당된 값의 자료형을 타입을 추론하게 된다.

타입스크립트 배열, 객체 예제

/* 배열타입 */
// 문자열만 있는 배열
let aaa:string[] = ["원두","은정","혜원"]

// 배열에 문자열과 숫자열을 같이 넣어두고 싶을 때
let fff:(string | number)[] = [1,2,3,"철수","영희"]

// 모두 숫자이거나 모두 문자인 배열
let hhh: string[] | nuber[] =[ "영희","철수" ]
hhh=[1,2,3]



/* 객체타입 */
interface IPropfile {
		name : string
		age : number 
		school : string
	}
const profile:IPropfile = {
		name : "원두"
		age : 8
		school : "코캠 초등학교"
	} 

//age의 타입이 문자열이거나 숫자열일 때
interface IPropfile{
		name : string
		age : string | number
		school : string
	}
const profile:IPropfile = {
		name : "원두"
		age : 8 or "8살"
		school : "코캠 초등학교"
	} 

❗️ 타입스크립트에서의 그리고와 또는

타입스크립트에서의 '또는' 과 '그리고'는 자바스크립트와 비슷하지만 약간 다르다.
또는 : |
그리고 : &

객체에서 해당 key와 value가 있을 경우 타입을 미리 정해주고 싶을 때
? 를 이용하면 된다!
?는 '있다면' 이라는 뜻이다.

❗️ props의 타입은 어떻게 지정할까?

props 또한 객체이기 때문에 객체의 타입을 지정하는 것과 동일하게 지정해주면 된다!

엄격한 타입스크립트, strict

타입스크립트의 설정 파일인 tsconfig.json 파일의 strict값을 true로 두게 되면 보다 엄격하게 타입을 지정해주어야 한다.
따라서 props로 받아오는 데이터의 타입도 지정해주어야 한다.
props는 주는 부모와 받는 자식이 있는데, 타입스크립트는 받게되는 자식 입장에서 타입을 지정해야 한다.

❗️ 함수의 타입 지정해주기

파라미터의 타입 또한 지정해주어야 한다.

/* props를 받는 쪽 컴포넌트 */
// 함수의 타입 지정해주기
// 리턴되는 값의 타입을 지정해주어야 한다. 
// 만일 리턴되는 값이 없다면 void를 적어주면 된다!
interface IProps {
  add: (a: number, b: number) => number;
}

const Component2 = (props: IProps) => {
  props.add(1, 2);
  return (
    //컴포넌트의 JSX부분
  );
};

💡 이벤트 핸들러 함수의 파라미터(event) 타입 지정하기

onChange, onClick 등의 함수를 사용할 때 적용할 수 있다.

// 이벤트 핸들러 함수가 적용된 태그를 지정해주어야 한다.
const onChangeMyWriter = (event: ChangeEvent<HTML InputElement>)=>{
			setMywriter(event.target.value)
	}

ChangeEvent는 리액트에서 제공해주는 타입이며 import를 하여 사용할 수 있다.

💡 타입스크립트는 항상 받는 쪽이 중심이다!

따라서 보내주는 쪽에서는 받겠다고 한 타입의 데이터를 보내주어야 한다!


유틸리티 타입

유틸리티 타입이란, 타입을 조작해서 필요한 타입만 따로 빼두거나 필요없는 타입은 제거하는 등 타입을 조작하는 방법이다.
유틸리티 타입을 사용하면 객체의 전체 key와 value 값을 필수 타입으로 설정하거나 전체를 옵션 타입으로 설정할 수도 있으며 특정 key의 타입만 사용하거나 제거하는 등도 가능하다.

유틸리티 타입의 종류

1. Partial

전체 타입을 optional 한 타입으로 변경한다.

type partial = Partial<IMyProfile>

2. Required

전체 타입을 required 한 타입으로 변경한다.

type requireds = Required<IMyProfile>

3. Pick

전체 타입에서 원하는 타입만 지정한다.

type picked = Pick<IMyProfile, "name", "age">
// name과 age 타입만 지정

4. Omit

전체 타입에서 원하는 타입만 제거한다.

type omits = Omit<IMyProfile, "school">
// school 타입만 제거 = name과 age 타입만 지정

5. Union Type

원하는 타입을 직접 지정할 수 있다.

type union = "school" | "name"
// school과 name 타입만 지정

6. Record

Union으로 지정된 타입을 순회하여 타입을 지정한다.

type union = "school" | "name"
type RecordType = Record<union, IMyProfile>
// school과 name의 각각의 타입에는 IMyProfile가 지정

API 응답 데이터의 타입

graphql-api의 경우, graphql-codegen을 이용하면 명령어 하나로 api 응답 데이터의 타입을 만들어준다.
(rest-api의 경우 어느 정도 직접 만들어야하는 부분이 있다.)

graphql-codegen

mutation에 타입스크립트 적용해보기

💡 예제

codegen을 사용하면 graphql의 타입을 모두 다운 받을 수 있다.
다운 받아온 타입 중 사용할 mutation에 맞는 타입을 뽑아서 적어주면 된다.

const [createBoard] = useMutation<Pick<IMutation, "createBoard">, IMutationCreateBoardArgs>(CREATE_BOARD);

const onClickUpload = async () => {
		const result = await createBoard(CREARTE_BOARD);
		console.log(result.data?.createBoard?.message);
	}

<>를 이용하여 타입을 작성하고, Pick을 사용하여 적용할 mutation인 createBoard를 뽑아서 작성해준다.

query에 타입스크립트 적용해보기

💡 예제

const { data } = useQuery<Pick<IQuery,"fetchBoard">,IQueryFetchBoardArgs>(FETCH_BOARD,{
		variables: {number: Number(router.query.mynumber)}
	})

💡 input태그의 readOnly 속성에서의 타입스크립트 오류

input 태그의 readOnly 속성은 boolean 타입이기 때문에 타입을 변경해주어야 한다!
이중부정연산자를 사용하여 문제를 해결할 수 있다.
data?.fetchBoard.writer는 string 타입이지만 빈 문자열이 아니기 때문에 true의 성격을 띈다.
따라서 !!를 붙여 이중 부정을 하면 boolean 타입이 true인 string 타입 데이터를 가져올 수 있게 된다.


💡 알게된 것

  • prompt 창을 이용하여 값(ex.비밀번호 등)을 입력받을 수 있다.
  • readOnly를 사용하여 입력이 불가능하게 막을 수 있다.
  • defaultValue는 초기값을 넣어주는 속성이고 value는 원하는 값을 정해주는 속성이다. (변경할 수 없게 지정)
  • if문을 중첩해서 사용하면 비효율적이기 때문에 잘못된 조건들을 먼저 return 시키는 early-exit 패턴을 사용하는게 효율적이다.
  • 리팩토링이란 결과값은 동일하되, 더 효율적인 코드로 업그레이드 하는 방법이다.
  • changeEvent : 리액트가 제공해주는 onChange 이벤트의 타입이다.
  • mouseEvent : 리액트가 제공해주는 마우스를 이용한 이벤트의 타입이다.
  • 함수의 리턴값이 없으면 타입으로 void를 설정해줄 수 있다.

🤔 궁금한 것

  • 어떻게 하면 효율적으로 모든 함수와 데이터에 타입을 지정해줄 수 있을까?
  • 유틸리티 타입을 사용하는 예시에 대해 궁금하다.

💖 느낀 점

타입스크립트에 대해 배웠다! 타입스크립트를 사용하는 회사나 개발자들이 점점 늘어나고 있다고 한다. 배워두면 경쟁력이 될 수 있을 것 같았는데 직접 배워보니 어째서 타입스크립트가 중요한지 훨씬 잘 이해하게 되었다. 타입을 지정해주고 강제해주어 치명적인 에러를 현저하게 줄일 수 있다는 점이 매우 중요하다고 생각한다. 타입을 지정해주는 과정은 번거롭고 귀찮은 과정이지만 한번 작업을 해두면 에러를 잡는 시간을 아낄 수 있을 것 같다. 아직은 타입을 지정해주는 작업이 많이 어색하고 특히 API 응답 데이터의 타입을 지정해주는 작업이 헷갈리지만 자연스럽게 타입을 딱딱 지정해줄 수 있도록 많이 적용해보아야겠다!

profile
프론트엔드 개발자가 꿈인 고슴도치

0개의 댓글