TypeScriptSTUDY _ 3장 . 고급타입 [ 3 .2 타입조합 ]

zeroha·2024년 11월 24일
0

TypeScriptStudy

목록 보기
7/32
post-thumbnail

1. 교차 타입 intersection

: 여러가지 타입을 결합하여 하나의 단일 타입으로 생성 ( 생성한 단일 타입에 별칭 붙이기 가능 )

  • 표기 : 어쩌구 & 저쩌구
type ProductItem = {
    id : number;
    name : string;
    quantity : number;
};

type ProductItemWithDiscount = ProductItem & {discountAmount : number};


2. 유니온 타입 union

: 타입 A 또는 타입 B 중 하나가 될 수 있는 타입

  • 표기 : 어쩌구 | 저쩌구
type ProductItem = {
    id : number;
    name : string;
    quantity : number;
};

type CardItem = {
    id : number;
    name : string;
    imgURL : string;
}

type PromotionEventItem = ProductItem | CardItem;

const printPromotionItem = (item : PromotionEventItem) => {
    console.log(item.name); //0

    console.log(item.quantity) // 컴파일 에러 발생
};

: 컴파일 에러 발생
-> quantity는 ProductItem에만 존재하기 때문에
CardItem는 quantity 멤버를 가지고 있지 않기 때문에 PromotionEventItem에서는 quantity 참조할 수 없다.

type PromotionEventItem =
 | ProductItem 
 | CardItem;

: 2개 이상의 타입을 이어 붙일 수 있고 타입 별칭을 통해 중복을 줄일 수 있음.
-> 여러줄에 걸쳐 표기 가능 : 맨 앞에 & 혹은 | 붙여서 표기


3. 인덱스 시그니처 index signatures

: 특정 타입의 속성 이름을 알 수 없지만 속성값의 타입을 알고 있을 대 사용하는 문법

  • 표기 : [ Key : K ] : T
    : 해당 타입의 속성 키는 모두 K 타입, 속성 값은 모두 T 타입.
interface IndexSignature1 {
    [key: string]: number
}

: name 은 string 타입을 가지도록 선언

interface IndexSignature2 {
    [key: string]: number | boolean;
    length: number;
    name : string; // 에러 발생
}

: 인덱스 시그니처의 키가 string일 때 number | boolean 타입 오게 선언 -> 에러 발생


4. 인덱스드 엑세스 타입 indexed accsee types

: 다른 타입의 특정 속성이 가지는 타입을 조회하기 위해 사용.
( 배열의 요소 타입을 조회 )

type Example = {
a: number;
b: string;
c: boolean;
}

type IndexedAccess = Example["a"];
type IndexedAccess2 = Example["a" | "b"]; // number / string
type IndexedAccess3 = Example[keyof Example]; // number / string i boolean

type ExAlias = "b" | "c";
type IndexedAccess4 = Example[ExALias]; // string i boolean

: 배열의 요소 타입 조회 -> 인덱스드 엑세스 타입 사용 하는 경우도 있음.
( 배열의 인덱스 : 숫자 타입 )
-> number로 인덱싱하여 배열요소를 얻은 다음 typeof연산자를 붙여주면 해당 배열 요소의 타입을 가져올 수 있다.

const PromotionList = [
{ type: "product", name: "chicken" }, 
{ type: "product", name: "pizza" }, 
{ type: "card", name: "cheer-up" },
];

type Elementof<T>= typeof T[number];

// type PromotionItemType = { type: string; name: string }
type PromotionItemType = ElementOf‹PromotionList>;

: PromotionList 배열을 정의하고, Elementof 타입을 사용하여 배열의 항목 타입을 추출하려고 하고 있는데,
근뎅 왜 오류가 날까잉?


5. 맵드 타입 mapped types

: 배열 A를 기반으로 새로운 배열 B를 만들어내는 배열 메서드

  • map : 유사한 형태를 가진 여러 항목의 목록 A -(변환)-> 변환된 항목의 목록 B

반복적인 타입 선언 줄이기 가능

맵드 타입 : 이러한 수식들을 제거도 가능
(기존 readonly나 ? 앞에 - 붙여주면 해당 수식어를 제거한 타입 선언 가능)

type BOTTOM_SHEET_ID = 'RECENT_CONTACTS' | 'CARD_SELECT' | 'SORT_FILTER';

type BottomSheetStore = {
  [index in BOTTOM_SHEET_ID]: {
    resolver?: (payload: any) => void;
    args?: any;
    isOpened: boolean;
  };
};

// 사용 예시:
const bottomSheetStore: BottomSheetStore = {
  RECENT_CONTACTS: { isOpened: true },
  CARD_SELECT: { isOpened: false },
  SORT_FILTER: { isOpened: true, resolver: (payload) => {} },
};

: BottomSheetStore 객체의 타입을 효율적으로 작성

  • BOTTOM_SHEET_ID 타입: 'RECENT_CONTACTS' | 'CARD_SELECT' | 'SORT_FILTER'로 유니온 타입을 정의하여 각 키를 제한
  • BottomSheetStore 타입: BOTTOM_SHEET_ID에 대한 매핑을 통해 각 키(RECENT_CONTACTS, CARD_SELECT, SORT_FILTER)에 대해 동일한 구조의 값을 할당

-> 이렇게 하면 새로운 시트를 추가하거나 기존 시트를 수정할 때, 반복적으로 동일한 구조를 작성할 필요 없이 확장 가능하게 사용가능

readonly : 읽기 전용
? : 선택적 매개 변수 (옵셔널 파라미터)

type BOTTOM_SHEET_ID = 'RECENT_CONTACTS' | 'CARD_SELECT' | 'SORT_FILTER';

type BottomSheetStore = {
[index in BOTTOM_SHEET_ID as `${index}_BOTTOM_SHEET`]: {
  resolver?: (payload: any) => void;
  args?: any;
  isOpened: boolean;
};
};

: 맵드 타입에서는 as 키워드르 사용 -> 키 재지정 가능


6. 템플릿 리터럴 타입 templete literal types

: 문자열 리터럴 타입 선언

type Stage =
| "init"
| "select-image"
| "edit-image"
| "decorate-card"
| "capture-image";
type StageName = `${Stage}-stage`;
// 'init-stage' | 'select-image-stage' | 'edit-image-stage' | decorate
'capture-image-stage'

: 모든 유니온 멤버 뒤에 -stage 붙여서 새로운 유니온 타입을 만들었다.
${Stage-stage}와 같이 변수 자리에 문자열 리터럴의 유니온 타입의 Stage를 넣으면 해당 유니온 타입(Stage 타입) 멤버들이 차례대로 변수에 들어가서 -stage가 붙은 문자열 리터럴의 유니온 타입을 결과로 반환
-> Stage 타입의 각 멤버에 -stage를 추가 : 새로운 문자열 리터럴 유니온 타입을 만들어 냄.


7. 제네릭 generic

: C나 자바 같은 정적 언어에서 다양한 타입 간에 재사용을 높이기 위해 사용하는 문법
( 제네릭의 사전적 의미 : 특징이 없거나 일반적인 것 )

  • 타입스크립트도 정적 타입을 가지는 언어 -> 제네릭 문법을 지원

함수, 타입, 클래스를 비워 둔 다음 실제로 그 값을 사용할 때 외부에서 타입 변수 자리에 타입을 지정하여 사용하는 방식. -> 여러 타입에 대해 따로따로 하나하나 정의하지 않아도 되서 재사용성이 크게 향상됨.

제네릭: 일반화된 데이터 타입 ( 아무 타입이나 무분별하게 받는 게 아니라, 배열 생성 시점에서 원하는 타입으로 특정 가능 )!= any 타입 ( 배열 요소들의 타입이 전부 같지 않을 수 있음 = 타입 검사를 하지 않아도 모든 타입이 허용 )

주의 ) 파일 확장자가 tsx일 때 화살표 함수에 제네릭을 사용하면 에러 발생
tsx는 타입스크립트 + jsx 이므로 제네릭의 꺾쇠괄호와 태그의 꺾쇠괄호를 혼동하며 문제 발생
해결 ) 제네릭 부분에 extends 키워드를 사용하여 컴파일러에 특정 타입의 하위 타입만을 올 수 있음을 명확히 해줘야 함. 보통 제네릭 사용할 때 function키워드로 선언하는 경우가 많음.


_ 도서참조 : 우아한 타입스크립트 with 리액트

profile
하 영

0개의 댓글

관련 채용 정보