: 여러가지 타입을 결합하여 하나의 단일 타입으로 생성 ( 생성한 단일 타입에 별칭 붙이기 가능 )
type ProductItem = {
id : number;
name : string;
quantity : number;
};
type ProductItemWithDiscount = ProductItem & {discountAmount : number};
: 타입 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개 이상의 타입을 이어 붙일 수 있고 타입 별칭을 통해 중복을 줄일 수 있음.
-> 여러줄에 걸쳐 표기 가능 : 맨 앞에 & 혹은 | 붙여서 표기
: 특정 타입의 속성 이름을 알 수 없지만 속성값의 타입을 알고 있을 대 사용하는 문법
interface IndexSignature1 {
[key: string]: number
}
: name 은 string 타입을 가지도록 선언
interface IndexSignature2 {
[key: string]: number | boolean;
length: number;
name : string; // 에러 발생
}
: 인덱스 시그니처의 키가 string일 때 number | boolean 타입 오게 선언 -> 에러 발생
: 다른 타입의 특정 속성이 가지는 타입을 조회하기 위해 사용.
( 배열의 요소 타입을 조회 )
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 타입을 사용하여 배열의 항목 타입을 추출하려고 하고 있는데,
근뎅 왜 오류가 날까잉?
: 배열 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 객체의 타입을 효율적으로 작성
-> 이렇게 하면 새로운 시트를 추가하거나 기존 시트를 수정할 때, 반복적으로 동일한 구조를 작성할 필요 없이 확장 가능하게 사용가능
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 키워드르 사용 -> 키 재지정 가능
: 문자열 리터럴 타입 선언
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를 추가 : 새로운 문자열 리터럴 유니온 타입을 만들어 냄.
: C나 자바 같은 정적 언어에서 다양한 타입 간에 재사용을 높이기 위해 사용하는 문법
( 제네릭의 사전적 의미 : 특징이 없거나 일반적인 것 )
함수, 타입, 클래스를 비워 둔 다음 실제로 그 값을 사용할 때 외부에서 타입 변수 자리에 타입을 지정하여 사용하는 방식. -> 여러 타입에 대해 따로따로 하나하나 정의하지 않아도 되서 재사용성이 크게 향상됨.
제네릭: 일반화된 데이터 타입 ( 아무 타입이나 무분별하게 받는 게 아니라, 배열 생성 시점에서 원하는 타입으로 특정 가능 )!= any 타입 ( 배열 요소들의 타입이 전부 같지 않을 수 있음 = 타입 검사를 하지 않아도 모든 타입이 허용 )
주의 ) 파일 확장자가 tsx일 때 화살표 함수에 제네릭을 사용하면 에러 발생
tsx는 타입스크립트 + jsx 이므로 제네릭의 꺾쇠괄호와 태그의 꺾쇠괄호를 혼동하며 문제 발생
해결 ) 제네릭 부분에 extends 키워드를 사용하여 컴파일러에 특정 타입의 하위 타입만을 올 수 있음을 명확히 해줘야 함. 보통 제네릭 사용할 때 function키워드로 선언하는 경우가 많음.
_ 도서참조 : 우아한 타입스크립트 with 리액트