[강의] TypeScript 기본기

김하은·2023년 12월 27일
0

코드잇 강의 정리

목록 보기
57/60
post-thumbnail

Enum

  • 중괄호 안에서 각 항목을 쉼표로 구분해서 적어주면 됨
  • 기본값은 0부터 시작하는 정수임
enum Size {
  S,
  M,
  L,
  XL,
}

console.log(Size.S); // 0
console.log(Size.M); // 1
console.log(Size.L); // 2
  • 숫자 0은 실수하기 쉽기 때문에 Enum을 사용할 땐 되도록이면 값을 정해놓고 쓰는 게 좋음
enum Size {
  S = 'S',
  M = 'M',
  L = 'L',
  XL = 'XL',
}

Interface

  • interface를 사용하는 방법은 interface를 쓴 다음, 객체 타입처럼 만들면 됨
interface Product {
  id: string;
  name: string;
  price: number;
  membersOnly?: boolean;
}
  • Interface를 상속하고 싶으면 Interface 이름 뒤에 extends를 적은 다음 부모 Interface 이름을 적어주면 됨

interface ClothingProduct extends Product {
  sizes: Size[];
}

const product1: ClothingProduct = {
  id: 'c001',
  name: '코드잇 블랙 후드 집업',
  price: 129000,
  membersOnly: true,
  sizes: [Size.M, Size.L],
};

const product2: Product = {
  id: 'd001',
  name: '코드잇 텀블러',
  price: 25000,
};

그 밖의 타입들

리터럴 타입

  • 특정한 숫자나 문자열 같이 변수의 값을 타입으로 하는 타입
  • 문자열 리터럴 타입은 문자열 타입에 포함되고 숫자 리터럴 타입은 숫자형 타입에 포함됨
const name = 'codeit'; // 'codeit' 이라는 리터럴 타입
const rank = 1; // 1 이라는 리터럴 타입

타입 별칭:

  • 타입도 변수처럼 이름을 붙여줄 수 있는데 이를 타입 별칭이라 함
  • 복잡한 타입에 이름을 붙이고 재사용하고 싶을 때 사용
  • 모든 타입에 사용할 수 있음
type Cart = string[];

type CartResultCallback = (result: boolean) => void;

type Prodect = {
  id: string;
  name: string;
}

interface Prodect = {
  id = string;
  name: string;
}

type Point = [number, number];
type SearchQuery = string | string[];
type Result = SuccessResult | FailedResult;
type Coupon = 
  | PromotionCoupon
  | EmployeeCoupon
  | WelcomCoupon
  | RewardCoupon
  ;   

Union 타입

  • A이거나 또는 B인 경우를 타입으로 만들고 싶을 때
ClothingProduct | ShoeProduct
  • 타입으로 연산도 가능함
  • if문을 활용하면 유니언 타입에서 특정 타입만 처리하도록 할 수 있음
enum ClothingSize {
  S = 'S',
  M = 'M',
  L = 'L',
  XL = 'XL',
}

interface Product {
  id: string;
  name: string;
  price: number;
  membersOnly?: boolean;
}

interface ClothingProduct extends Product {
  sizes: ClothingSize[];
  color: string;
}

interface ShoeProduct extends Product {
  sizes: number[];
  handmade: boolean;
}

function printSizes(product: ClothingProduct | ShoeProduct) {
  const availableSizes = product.sizes.join(', '); // 공통된 프로퍼티만 참조할 수 있음
  console.log(`구매 가능한 사이즈는 다음과 같습니다: ${availableSizes}`);
  
  if ('color' in product) {
    console.log(`색상: ${product.color}`);
  }
}
  
  if ('handmade' in product) {
      console.log(
      product.handmade 
      ? '이 상품은 장인이 직접 만듭니다.' 
      : '이 상품은 공장에서 만들어졌습니다.'
    );
  }
}

const product1: ClothingProduct = {
  id: 'c001',
  name: '코드잇 블랙 후드 집업',
  price: 129000,
  membersOnly: true,
  sizes: [ClothingSize.M, ClothingSize.L],
  color: 'black',
};

const product2: ShoeProduct = {
  id: 's001',
  name: '코드잇 스니커즈',
  price: 69000,
  membersOnly: false,
  sizes: [220, 230, 240, 260, 280],
  handmade: false,
};

printSizes(product1);
printSizes(product2);
  • 리터럴 값과 사용하면 유용함

Intersection

  • A와 B의 성질을 모두 갖는 타입을 만들고 싶을 때
interface Entity {
  id: string;
  createdAt: Date;
  updatedAt: Date;
}

type Product = Entity & {
  name: string;
  price: number;
  membersOnly?: boolean;
}
  • 하지만 보통 이럴 때는 interface와 상속을 사용하는 걸 권장함
interface Entity {
  id: string;
  createdAt: Date;
  updatedAt: Date;
}

interface Product extends Entity {
  name: string;
  price: number;
  membersOnly?: boolean;
}

keyof 연산자

  • 객체 타입에서 프로퍼티 이름들을 모아서 Union한 타입으로 만들고 싶을 때 사용
interface Product {
  id: string;
  name: string;
  price: number;
  membersOnly?: boolean;
}

type ProductProperty = keyof Product; // 'id' | 'name' | 'price' | 'membersOnly';

typeof 연산자

  • 자바스크립트 코드에서 사용하면 결괏값이 문자열이지만, 타입스크립트 코드에서 쓸 때는 결과 값은 타입스크립트의 타입임
const product: Product = {
  id: 'c001',
  name: '코드잇 블랙 후드 집업',
  price: 129000,
  salePrice: 98000,
  membersOnly: true,
};

console.log(typeof product); // 문자열 'object'

const product2: typeof product = { // 타입스크립트의 Product 타입
  id: 'g001',
  name: '코드잇 텀블러',
  price: 25000,
  salePrice: 19000,
  membersOnly: false,
};

타입 별칭은 언제 쓰면 좋을까?

  • 타입 별칭은 타입에 '이름'을 정하는 문법임
  • 복잡한 타입을 만들고, 그 타입을 여러 곳에서 활용할 때 사용하면 됨

제네릭

  • <>안에 임의의 타입을 정의해 놓고 그때 그때 다른 타입을 넣어서 쓸 수 있도록 하는 문법
  • 보통 알파벳 T, U, V로 나타내며 Type parameter를 나타냄
const shoeSizes: number[] = [230, 250, 280];
shoeSizes.map((num) => {

});

const clothingSizes: string[] = ['M', 'L', 'XL'];
clothingSizes.map((names) => {

});

function printArray<T>(items: T[]) {
  for (const item of items) {
    console.log(item);
  }
}

printArray(shoeSizes);
printArray(clothingSizes);

알아두면 유용한 제네릭 타입들

JavaScript 기능들

querySelector() 함수

  • 기본적으로 어떤 DOM 노드가 리턴될지 모르기 때문에 HTMLElement라는 일반적인 타입으로 정의됨
  • 타입을 확신할 수 있는 경우에는 아래 코드처럼 직접 제네릭 타입을 정의해 주면 됨
const elem = document.querySelector<HTMLInputElement>('input.username');

Map

  • 키와 밸류를 갖는 자료구조로 타입 파라미터로 키와 밸류의 타입을 정의하고 사용할 수 있음
const productMap = new Map<string, Product>();
productMap.set(product1.id, product1);
productMap.set(product2.id, product2);

Set

  • 배열과 비슷하지만 중복된 요소를 추가할 수 없는, 수학에서 집합에 해당하는 자료구조임
  • 타입 파라미터로 요소의 타입을 정의하고 사용할 수 있음
const productSet = new Set<Product>();
productSet.add(product1);
productSet.add(product2);

유용한 타입들

키와 밸류 정하기: Record

  • 객체에 키와 밸류 타입을 정해놓고 싶을 때 사용함
  • Map과 비슷하지만 차이점은 순수한 객체에 타입만 추가한다는 점
const productMap: Record<string, Product> = {}
productMap['c001'] = product1;
productMap['c002'] = product2;

객체 프로퍼티 고르기: Pick

interface Product {
  id: string;
  name: string;
  price: number;
  membersOnly?: boolean;
}

type ProductInfo = Pick<Product, 'name' | 'price'>;
  • Pick으로 만든 타입은 아래와 같으며 name 프로퍼티와 price 프로퍼티만 골라서 타입을 만듦
type ProductInfo = {
    name: string;
    price: number;
} 

객체의 프로퍼티 생략하기: Omit

interface Product {
  id: string;
  name: string;
  price: number;
  membersOnly?: boolean;
}

type ProductInfo = Omit<Product, 'id' | 'membersOnly'>;
  • Omit으로 만든 타입은 아래와 같으며 id와 membersOnly를 제외하고 타입을 만듦
type ProductInfo = {
    name: string;
    price: number;
} 

Union 제거하기: Exclude

  • Employee Coupon에 해당하는 것만 제거를 하고 싶을 때 Exclude를 사용할 수 있음
type Coupon = 
  | PromotionCoupon
  | EmployeeCoupon
  | WelcomCoupon
  | RewardCoupon
  ;

type InternalCoupon = EmployeeCoupon;
type PublicCoupon = Exclude<Coupon, InternalCoupon>;
// type PublicCoupon = PromotionCoupon | WelcomCoupon | RewardCoupon

함수 파라미터 타입 가져오기: Parameters

  • 함수 파라미터들의 타입을 함수의 타입을 통해 정의할 수 있음
  • 만약 함수의 타입이 아니라, 선언된 함수라면 typeof 연산자로 함수의 타입으로 만들어서 사용하면 됨
function addToCart(id: string, quantity: number = 1): boolean {
  // ...
  return true;
}

type AddToCartParameters = Parameters<typeof addToCart>;
// type AddToCartParameters = [id: string, quantity: number | undefined]

함수 리턴 타입 가져오기: ReturnType

  • Parameters와 마찬가지로 함수의 리턴 타입을 가져옴
function addToCart(id: string, quantity: number = 1): boolean {
  // ...
  return true;
}

type AddToCartResult = ReturnType<typeof addToCart>;
// type AddToCartResult = boolean
profile
아이디어와 구현을 좋아합니다!

0개의 댓글