TypeScript : JS / 리액트에서 타입스크립트 사용하기

728x90
반응형

★ 재상 튜터님의 TS + React Cookbook

 

(1) 함수에서 TS 사용하기

function sum(a: number, b: number): number {
  return a + b;
}

function objSum({ a, b }: { a: number; b: number }): string {
  return `${a + b}`;
}

 

1) sum ( 타입 지정 해주기)  : return 의 타입 지정

2) 객체의 타입 지정시 묶어서 지정.

 

 

(2) 비동기 함수에서 TS 사용하기

type Person = { id: number; age: number; height: number };

async function getPerson(): Promise<Person[]> {
  const res = await fetch(`http://localhost:5008/people`);
  if (!res.ok) {
    throw new Error();
  }
  return res.json();
}

getPerson().then((res) => console.log(res[0]));

 

0) 위에 Person으로 타입 지정해주기

1) 반환값은 배열 객체여서 person[ ] 로 표시 => 오류 발생

2) 이유 : async 비동기함수여서 return 값은 promise 임

3) 함수 선언부에 Promise<Person[ ]> 으로 타입 작성 필요

 

* return 부분에서 타입을 지정해줘도 가능

" return res.json() as any as Person[ ]" 이렇게도 사용 가능 => 복잡함

 

 

(3) 꿀팁

1)  typeScript 템플릿으로 프로젝트 생성

npx create-react-app my-first-ts-app --template typescript

 

2) 타입 에러 : Pretty TypeScript Errors 패키지 설치하기

 

(4) 제네릭

- 어떤 데이터 타입을 일반화 = 제네릭 = 타입을 변수화 한다.

// 제네릭(generic)이란 데이터의 타입(data type)을 일반화한다(generalize)는 것을 의미합니다.
type Generic<T> = {
  someValue: T;
};

type Test = Generic<string>;

function someFunc<T>(value: T) {}

someFunc<string>("hello");

1) 타입인 T를 주입받아서 someValue:여기에 사용할 수 있게됨

- 타입을 생성할때, 원하는인자를 받아서 넣어주기

 

- 함수에서도 인자로 사용할 수 있음

=> function  someFunc<T> (value:T) {}

=> someFunc<string>(); ----> value에도 string으로 들어간 것 확인 가

 

(5) useState 에서 사용하기

- useState옆에 원하는 타입만 넣어주기 ! : useState<number>

- useState() : 초기값이 비어있으면 undefined 오류 발생 =>꼭 값을 넣어주기

import { useState } from "react";

function App() {
  const [counter, setCounter] = useState<number>(1);
  const increment = () => {
    setCounter((prev) => prev++);
  };
  return <div onClick={increment}>{counter}</div>;
}

export default App;

 

 

(6) Passing Props

- props에 타입 넣어주기 : Child ( {count} : {count:string} )

- useState() 초기값 비어있으면 undefined 오류 발생하니 꼭 넣어주기 

- type 부분만 선언 가능 : 그 후에 {count} : Props로 작성해주기 (가독성에 좋음)

import { useState } from "react";

function Parent() {
  const [count, setCount] = useState("");
  return <Child count={count}></Child>;
}

type Props = {
  count: string;
};

function Child({ count }: Props) {
  return <div>{count}</div>;
}

export default Parent;

 

(7) Children Props

- FC = functional components => React 18버전 이전에 가능

- 문제 : 암묵적으로 사용할 수 있는 부분이 오류가 되었음 => 18번전 이후에는 불가능하도록 조치됨

type BaseType = {
  id: string;
};

//React 18버전 이전
const Child: React.FC<BaseType> = ({ id }) => {
  return <div>{id}</div>;
};

export function Parent() {
  return (
    <Child id="">
      <div>has children</div>
    </Child>
  );
}

 

 

- 명시적인 친구 : PropsWithChildren 

- BaseType을 제네릭에 넣어주기만하면! 바로 children props를 사용가능

- 문제점 : children을 옵셔널하게 갖음. >> ReactNode 와 Undefined와 동시에 갖음 

=>  children이 들어가지 않았을때도 오류를 보여주지 않음

import { PropsWithChildren } from "react";

type BaseType = {
  id: string;
};

function Child({ children }: PropsWithChildren<BaseType>) {
  return <div>{children}</div>;
}

export function Parent() {
  return <Child id=""></Child>;
}

 

 

- 엄격한 타입 : StrictChildren

import { ReactNode } from "react";

type BaseType = {
  id: string;
};

type StrictChildren<T> = T & { children: ReactNode };

function Child({ children }: StrictChildren<BaseType>) {
  return <div>{children}</div>;
}

export function Parent() {
  return (
    <Child id="">
      <div>chlidren</div>
    </Child>
  );
}

 

 

(8) Generic, Utility Type 통해서 Props용 Type 만들기

- children을 옵셔널하게 받을 수 있다 =  PropsWithChildren => 제네릭을 사용하지 않더라도 children만 추가 가능

 

import {
  AddressComponent,
  PersonChildComponent,
  ProfileComponent,
} from "./UtilityTypeChildren";

export type PersonProps = {
  id: string;
  description: string;
  address: string;
  age: number;
  profile: string;
};

export const PersonComponent = ({
  id,
  description,
  address,
  age,
  profile,
}: PersonProps) => {
  return (
    <>
      <PersonChildComponent>
        <div>{id}</div>
      </PersonChildComponent>
      <ProfileComponent
        description={description}
        address={address}
        age={age}
        profile={profile}
      />
      <AddressComponent address={address} />
    </>
  );
};

 

 

- 5개인 PersonProps에서 ProfileComponent에 4개만 필요함

=>Omit<PersonProps, "id">  : id만 빼고 타입을 만들어줘!

import { PropsWithChildren, ReactNode } from "react";
import { PersonProps } from "./UtilityType";

export const PersonChildComponent = ({ children }: PropsWithChildren) => {
  return <>{children}</>;
};

type OmitType = Omit<PersonProps, "id">;

export const ProfileComponent = ({
  description,
  address,
  age,
  profile,
}: OmitType) => {
  return <></>;
};

type PickType = Pick<PersonProps, "address">;

export const AddressComponent = ({ address }: PickType) => {
  return <></>;
};

- Pick은 원하는 타입만 골라서 사용 가능 

 

(9) Event Handler 사용하기

- onClick 이벤트 타입 : (e: React.MouseEvent<HTMLDivElement>)

- onChange 이벤트 타입 : (FormEvent<HTMLDivElement>) 

- 이벤트에 호버해서 가져다가 사용하기

import { useState } from "react";

function App() {
  const [counter, setCounter] = useState<number>(1);
  const eventHandler = (e: React.MouseEvent<HTMLDivElement>) => {};
  return <div onClick={eventHandler}>{counter}</div>;
}

export default App;

 

 

 

끝.

반응형