타입 정의

강연주·2025년 4월 18일

📚 TIL

목록 보기
156/186
import React from "react";
import { TypePurposeType } from "@/types/meetupType";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "@/stores/store";
import { resetFilter, setCatregory } from "@/stores/filterSlice";const CategoryButtons = () => {
  const dispatch = useDispatch();
  const { category } = useSelector((state: RootState) => state.filter);
  const categories: TypePurposeType[] = ["운동", "공부", "취준", "취미", "친목", "맛집", "여행", "기타"];  const handlePurposeSelect = (newCategory: TypePurposeType) => {
    if (category === newCategory) {
      dispatch(resetFilter());
    } else {
      dispatch(setCatregory(newCategory));
    }
  };  return (
    <>
      <div>
        {categories.map(categoryItem => (
          <button
            key={categoryItem}
            onClick={() => handlePurposeSelect(categoryItem)}
            className={px-3 py-1 text-sm rounded-lg border ${category === categoryItem ? "bg-blue-200 border-blue-300 text-blue-900" : "bg-gray-200 border-gray-400 text-gray-800"}}
          >
            {categoryItem}
          </button>
        ))}
      </div>
    </>
  );
};export default CategoryButtons;

근데 여기서 categories의 내용들을 또 배열안에 넣어서 다시 정의할 필요가 있어? 기존 타입을 가져와서 그냥 쓰면 안돼? 문법을 잘 모르겠네

편집좋은 질문입니다. 타입 정의만 가져와서는 실제 값의 배열을 얻을 수 없습니다. 타입스크립트의 타입 정보는 컴파일 시간에만 존재하고 런타임에는 사라지기 때문입니다.
TypePurposeType 타입은 다음과 같이 정의되어 있을 겁니다:
typescriptexport type TypePurposeType = null | "운동" | "공부" | "취준" | "취미" | "친목" | "맛집" | "여행" | "기타";
이것은 실제 값이 아니라 가능한 값의 타입을 명시한 것입니다. 따라서 컴포넌트에서 이 값들의 배열을 사용하려면 직접 배열을 정의해야 합니다.
개선할 수 있는 방법이 있다면:

타입과 값 배열을 한 곳에서 관리하는 것입니다:

typescript// meetupType.ts 파일에서
export const CATEGORIES = ["운동", "공부", "취준", "취미", "친목", "맛집", "여행", "기타"] as const;
export type TypePurposeType = (typeof CATEGORIES)[number] | null;
이렇게 하면 CATEGORIES 배열을 가져와서 사용할 수 있습니다:
typescriptimport { CATEGORIES } from "@/types/meetupType";

const CategoryButtons = () => {
  // ...
  // categories 배열 대신 CATEGORIES 사용
  return (
    <>
      <div>
        {CATEGORIES.map(categoryItem => (
          // ...
        ))}
      </div>
    </>
  );
};

이 방식을 사용하면 타입과 실제 값을 동기화하기 쉽고, 한 곳에서 관리할 수 있습니다. 값이 변경되면 타입도 자동으로 업데이트됩니다.


TypePurposeType[] = ["운동", "공부", "취준", "취미", "친목", "맛집", "여행", "기타"]; 그럼 이 문법은 TypePurposeType이라는 타입을 가진 배열에 실제 값을 운동, 공부, 취준 등으로 넣은 배열을 만든다는 거지?
// meetupType.ts 파일에서 export const CATEGORIES = ["운동", "공부", "취준", "취미", "친목", "맛집", "여행", "기타"] as const; export type TypePurposeType = (typeof CATEGORIES)[number] | null; 이 문법을 한줄한줄 다 설명해줘
편집
네, 질문하신 내용에 대해 자세히 설명해 드리겠습니다.

  1. TypePurposeType[] = ["운동", "공부", "취준", "취미", "친목", "맛집", "여행", "기타"];
    이 문법은 정확히 말씀하신 대로입니다:

TypePurposeType[]은 "TypePurposeType 타입의 값들로 이루어진 배열" 타입을 의미합니다.
= ["운동", "공부", ...] 부분은 해당 타입의 배열에 실제 값들을 할당하는 것입니다.
즉, TypePurposeType이라는 타입의 값들을 담는 배열 변수를 선언하고, 그 값으로 "운동", "공부" 등을 넣는 것입니다.

  1. 두 번째 코드 설명
    typescript
    export const CATEGORIES = ["운동", "공부", "취준", "취미", "친목", "맛집", "여행", "기타"] as const;
    export const CATEGORIES: CATEGORIES라는 상수를 선언하고 외부에서 가져다 쓸 수 있게 내보냅니다.
    ["운동", "공부", ...]: 문자열 배열을 생성합니다.
    as const: 이 배열을 "읽기 전용(readonly)"으로 만들고, 각 요소의 타입을 정확한 리터럴 타입으로 설정합니다.
    일반 배열 선언은 string[] 타입이 되지만, as const를 사용하면 readonly ["운동", "공부", ...] 같은 튜플 타입이 됩니다.
    이렇게 하면 더 정확한 타입 추론이 가능합니다.
    typescript
    export type TypePurposeType = (typeof CATEGORIES)[number] | null;
    export type TypePurposeType: TypePurposeType이라는 타입을 선언하고 내보냅니다.
    typeof CATEGORIES: CATEGORIES 상수의 타입을 가져옵니다 (위에서 as const로 선언했으므로 이건 readonly ["운동", "공부", ...] 형태가 됩니다).
    [number]: 배열 타입에서 모든 원소의 타입을 추출합니다. 이 경우 "운동" | "공부" | ... 같은 유니온 타입이 됩니다.
    | null: null 값도 허용합니다.
    결과적으로 TypePurposeType은 "운동" | "공부" | "취준" | ... | null 처럼 모든 카테고리 문자열과 null을 포함하는 유니온 타입이 됩니다.

이 방식의 장점은 CATEGORIES 배열을 변경하면 TypePurposeType 타입도 자동으로 업데이트된다는 것입니다. 값과 타입을 동기화하기 쉬워집니다.

튜플 타입이 뭐야

편집
튜플(Tuple) 타입은 TypeScript에서 특정 길이와 각 위치마다 특정 타입을 가진 배열을 정의하는 방법입니다.

일반 배열과 튜플의 차이점은:

일반 배열:
모든 요소가 같은 타입을 가집니다.
길이가 가변적입니다.
예: string[] - 문자열만 담을 수 있는 길이 제한이 없는 배열
튜플:
각 위치마다 다른 타입을 가질 수 있습니다.
길이가 고정되어 있습니다.
각 위치의 값이 특정 의미를 가집니다.
예: [string, number, boolean] - 첫 번째는 문자열, 두 번째는 숫자, 세 번째는 불리언 값을 가진 정확히 3개 요소를 갖는 배열
예를 들어:

typescript
// 일반 배열: 문자열만 담을 수 있는 배열
const names: string[] = ["Alice", "Bob", "Charlie"];

// 튜플: 첫 번째는 문자열, 두 번째는 숫자인 배열
const nameAndAge: [string, number] = ["Alice", 30];
as const를 사용하면 일반 배열을 읽기 전용 튜플로 변환할 수 있습니다:

typescript
// 일반 배열: 타입은 string[]
const colors = ["red", "green", "blue"];

// 읽기 전용 튜플: 타입은 readonly ["red", "green", "blue"]
const colorsConst = ["red", "green", "blue"] as const;
튜플은 관련된 값들을 그룹화하면서도 각 위치에 특정 타입을 부여하고 싶을 때 유용합니다. 특히 함수에서 여러 값을 반환할 때 자주 사용됩니다.

profile
아무튼, 개발자

0개의 댓글