[WIL] react + typescript

kimi·2024년 1월 15일
4
post-thumbnail

✒️ 𝓦𝓮𝓮𝓴𝓵𝔂 𝓘 𝓛𝓮𝓪𝓻𝓷𝓮𝓭

리액트 + 타입스크립트 프로젝트 생성하여 자주 쓰이는 타입들을 적용시켜보기

vscode에서 리액트 타입스크립트 프로젝트를 생성하는 명령어입니다

// Use npm
npx create-react-app 프로젝트명 --template typescript
// Or yarn
yarn create-react-app 프로젝트명 --template typescript

React.FC

React Function Component 의 줄임말로
함수 컴포넌트를 정의할 때 사용되는 타입

속성(props)에 대한 타입을 지정하여
TS는 해당 컴포넌트가 어떤 속성을 받아야하는지 알 수 있고,
코드 작성 중 정보를 활용할 수도 있습니다


const App: React.FC = () => {

    return (
        <>
           // 컴포넌트
        </>
    );
};

export default App;

한 마디로 정의하기 어려운(string? number?)
객체 형 타입은 직접 타입을 만들어 줄 수 있습니다

// 객체형 타입
let data: Pet = {
    name: '나비',
    species: 'RussianBlue',
    age: 4,
    owner: {
        name: 'kimi',
        gender: 'female',
        age: 22,
    },
    snack: [
        { name: '츄르', price: 5000 },
        { name: '생선', price: 9900 },
        { name: '참치캔', price: 3000 },
    ],
};

typeAlias

원시 값이나 객체 등 다양한 타입을 정의할 수 있는 타입

위 예제의 Pet Type을 만들어보겠습니다

// typeAlias
// type을 쓸 수 있도록 export!
export type Pet = {
    name: string;
    species: string;
    age: number;
    // 타입안에 타입만들기
    owner: Owner;
    // snack은 type이 Snack인 Array[]가 된다.
    snack: Snack[];
};

export type Owner = {
    name: string;
    gender: string;
    age: number;
};

export type Snack = {
    name: string;
    price: number;
};

// Owner 에서 Gender속성 생략 -> ?로도 대체가 가능해요
export type OwnerWithOutGender = Omit<Owner, 'gender'>;
// Pet type에서 species만 가져올래요
export type PetOnlySpecies = Pick<Pet, 'species'>;

이런식으로 typeAlias는 타입안에 타입을 만들어 사용할 수 있으며,
OmitPick을 통하여 특정 속성을 생략하거나 뽑아쓸 수 있습니다


Generic <>

제네릭을 통해 타입을 지정하면 런타임 시점이 아닌
컴파일 시 타입이 지정됩니다

타입을 명시적으로 지정할 수 있기 때문에
타입 안정성을 강화할 수 있습니다

함수의 매개변수처럼 나중에 대입하도록하여
재사용성도 높아집니다


아래의 useState는 리액트에서 제공해주는 함수입니다

useState의 값으로 number가 들어갈지 string이 들어갈지?
-> 사람마다 다르게 씁니다
-> 제네릭을 활용하면 useState를 부르는 순간 타입이 지정됩니다

import React, { useState } from 'react';
import { Owner, Pet } from './model/pet';
import Info from './Info';

let data: Pet = {
    name: '나비',
    species: 'RussianBlue',
    age: 4,
    owner: {
        name: 'kimi',
        gender: 'female',
        age: 22,
    },
    snack: [
        { name: '츄르', price: 5000 },
        { name: '생선', price: 9900 },
        { name: '참치캔', price: 3000 },
    ],
};

const App: React.FC = () => {
    // 앞으로 useState는 Pet타입으로 쓰이게 됩니다
    const [myPet, setMyPet] = useState<Pet>(data);
    // owner 매개변수의 타입지정
    const changeOwner = (owner: Owner) => {
        setMyPet({ ...myPet, owner: owner });
    };

    return (
        <>
            <Info info={myPet} changeOwner={changeOwner} />
        </>
    );
};

export default App;

Pet의 정보를 보여주는 컴포넌트 Info입니다
function changeOwner의 타입은 return타입이 없는 경우 :void
지정할 수 있습니다

import { Owner, Pet } from './model/pet';
import React from 'react';

// 이곳에서만 쓰이는 props type
interface OwnProps {
    info: Pet;
    // 함수 매개변수의 타입 지정 / return type이 없는 함수: void
    changeOwner(owner: Owner): void;
}

// React Function Component에 들어오는 type지정
const Info: React.FC<OwnProps> = ({ info }) => {
    return (
        <>
            <p style={{ fontWeight: '800' }}>Info입니다</p>
            <div>{info.name}</div>
        </>
    );
};

export default Info;

Plus!

typeAlias와 interface는 모두 확장이 가능합니다
interface는 extend로,
typeAlias는 &로 확장이 가능합니다

// Snack Type에서 price만 뺀 타입을 가져오고 싶어요
interface OwnProps extends Omit<Snack, 'price'> {
    //추가 하고싶은 사항들 추가하기
}
/*
 * interface = extends로 확장
 * typeAlias = &로 확장
 */
type OwnProps  = Snack & {
   showHandMadeSnackName(name: string): string;
}

📓 𝓜𝓮𝓶𝓸𝓲𝓻𝓼
이제 막 타입스크립트를 시작하는 입장에서는
일일이 타입을 부여하는 것이 귀찮은 작업처럼 느껴졌습니다

그러나 유지보수하거나 협업하는 관점에서 생각해보면,
type safety한 환경에서 작업하고
타입정보를 통해 코드를 이해하고 해석할 수 있어서
실무에서 쓰기 유용할 거 같습니다

동적 타입 언어인 자바스크립트의 타입 관련 에러를
예방할 수 있으니, 제대로 배워서 쓰면 좋을 거 같습니다


profile
no namae wa

1개의 댓글

comment-user-thumbnail
2024년 1월 21일

잘 봤습니다 ㅎㅎ

답글 달기