준영이의 성장일기(FrontEnd)

타입 선언과 타입 단언 본문

프론트엔드/TypeScript

타입 선언과 타입 단언

Jay_Jung 2024. 8. 1. 15:06

프로젝트 진행과정에서 코드 리뷰를 통해서 팀원 분이 타입 단언으로 된 부분을 타입 선언으로 바꾸면 어떨까요 라고 제안을 해주셨다. 물론 버튼 한개에 대한 타입이라서 단언을 통해 간편하게 구현했지만 타입스크립트 특성 상 선언을 이용해 하는 것이 더 효과적이라 생각이 들었고 리뷰 내용을 현재 코드에 적용해보았다. 

 

적용한 코드는 다음과 같고 이후 타입 선언과 타입 단언에 대해서 정리하고자 한다.(구글링, 타입스크립트 교과서 책 참고)

import React, { useState } from 'react'
import {
  PageContainer,
  Header,
  BackButton,
  SubTitle,
  Title,
  EditOptions,
  OptionButton,
  NextButton,
} from '@pages/StoreInfoEditPage/StoreInfoEditPage.style'
import { Option } from 'src/types/ButtonOpionTypes'
import { useNavigate } from 'react-router-dom'

export default function StoreInfoEditPage() {
  const navigate = useNavigate()

  const [selectedOption, setSelectedOption] = useState<string | null>(null)

  const options: Option[] = [
    { label: '기본 정보', type: 'default', route: '/basic-info' },
    { label: '영업 시간', type: 'default', route: '/business-hours' },
    { label: '메뉴 등록', type: 'default', route: '/menu-registration' },
    { label: '가게 삭제', type: 'destructive', route: '/storeInfo-delete' },
  ]

  const handleOptionClick = (option: string) => {
    setSelectedOption(option)
  }

  const handleNextClick = () => {
    const selected = options.find((option) => option.label === selectedOption)
    if (selected) {
      navigate(selected.route)
    }
  }

  return (
    <PageContainer>
      <Header>
        <BackButton onClick={() => navigate('/manager')}>&lt;</BackButton>
        <Title>가게 정보 수정</Title>
      </Header>
      <SubTitle>
        {/* 고서현 사장님 부분은 로그인 정보 받아와서 이름으로 랜더링 해주기 */}
        고서현 사장님! <br />
        어떤 정보를 수정할까요?
      </SubTitle>
      <EditOptions>
        {options.map((option) => (
          <OptionButton
            key={option.label}
            active={selectedOption === option.label ? option.type : undefined}
            onClick={() => handleOptionClick(option.label)}
            type={option.type}
          >
            {option.label}
          </OptionButton>
        ))}
      </EditOptions>
      <NextButton onClick={handleNextClick}>다음</NextButton>
    </PageContainer>
  )
}

 

✅ types폴더 안에 ButtonOptionTypes.ts를 만들었고 해당 파일에 타입별칭, 인터페이스를 통해 타입을 설정했다.

✅ type 속성 같은경우 default 또는 destructive 중 하나 이기에 OptionType라는 타입 별칭을 따로 만들어 적용하였다.( 유니언 타입 ➡️ |  : 하나의 변수가 여러 타입을 가질 수 있다는 것을 알려줌 )

type OptionType = 'default' | 'destructive'

export interface Option {
  label: string
  type: OptionType
  route: string
}

 

그럼 타입선언과 타입 단언은 뭘까?

 

- 타입 선언

interface Person {
  name: string;
}

➡️ 인터페이스로 Pereson이라는 타입 선언

1. 타입 선언은 :을 이용하여 변수의 타입을 선언 ( Ex. const  alice : Person =  {name : 'Alice'} )

 

- 타입 단언

1. 타입 단언은 as을 이용하는데 타입스크립트가 추론한 타입이 있더라도 as 뒤에 붙여진 타입으로 간주한다. 즉 강제적으로 타입을 지정하는 것이다.

 

 

어떤 걸 사용하는 것이 좋을까?

  • 타입 선언을 이용하면 할당되는 값이 선언된 타입을 만족하는지 검사한다.
  • 반면, 타입 단언은 강제로 타입을 지정하는 것이기 때문에 타입체커는 할당되는 값이 타입을 만족하지 않더라도 오류를 무시한다. 그래서 타입을 확신할 수 있는 경우에는 타입 단언을 이용해도 된다.
  • 안전성 있는 타입 체크를 위해서 타입 단언보다 타입 선언을 사용해야 한다.