aotoyae

[TS] any 타입, 함수에 타입 정의하기 본문

TypeScript

[TS] any 타입, 함수에 타입 정의하기

aotoyae 2024. 3. 4. 18:39

 

 

💡 any 타입에 대해 알아보자.

 

let product: any = { // 타입을 any 로 지정하면 js 파일과 같이 타입 검사를 하지 않는다.
  id: 'c001',
  name: '주전자',
  price: 129000,
  membersOnly: true,
  sizes: ['M', 'L', 'XL'],
};

console.log(product.reviews[2]); // 프로덕트에 리뷰라는 프로퍼티는 없지만 에러가 뜨지 않는다.

 

😲 TS 에서 타입 검사를 없애주는 any 는 왜 필요한가 ?

어쩔 수 없이 any 로 바꿔줘야하는 경우가 있기 때문

 

JSON 문자열을 파싱한다고 할 때, JSON.parse 함수에선

어떤 문자열이 어떤 객체 타입으로 될지 알 수 없어서 그 결과값이 any 타입이다!

 

 

이럴 때 any 타입을 그대로 쓰기 보단, 타입을 정의해 두는게 좋다.

// 변수에 타입을 지정해주거나
const parsedProduct: {
  name: string;
  price: number;
} = JSON.parse('{ "name": "주전자", "price": 12900}');

// 값의 타입을 정해줄 수 있다.
const parsedProduct = JSON.parse('{ "name": "주전자", "price": 12900}') as {
  name: string;
  price: number;
};

 

 

💡 함수에 타입을 정의해보자!

타입을 정해주지 않아서 에러가 뜨고 있다.

 

✳️ 함수 선언에서 타입 정해주기

const stock: { [id: string]: number } = {
  c001: 3, // 프로퍼티 이름 = 상품 코드 문자열, 값 = 재고 숫자
  c002: 1,
};

const cart: string[] = []; // 장바구니

// 함수 결과값도 : boolean 으로 지정해뒀는데
// 지금은 결과값이 알아서 추론되고 있으니 적지 않아도 괜찮다.
function addToCart(id: string, quantity: number): boolean { // 장바구니에 넣을 상품코드, 갯수
  if (stock[id] < quantity) {
    return false;
  }

  stock[id] -= quantity;
  for (let i = 0; i < quantity; i++) {
    cart.push(id);
  }

  return true;
}
function sum(a: number, b:number): number { // 매개변수 넘기기
  return a + b;
}

function objsum({ a, b }: { a: number, b:number }): string { // 객체로 넘기기
  return `${a + b}`;
}

 

❗️ quantity 파라미터를 쓸 수 도 있고 안 쓸 수도 있다면?

객체에서와 마찬가지로 파라미터 뒤 ? 를 넣어주고 조건문을 추가한다.

function addToCart(id: string, quantity?: number): boolean {
  if (typeof quantity === 'undefined') {
    quantity = 1;
  }

  //..
}

 

보통은 그냥 타입 뒤 기본값을 작성해 준다.

function addToCart(id: string, quantity: number = 1): boolean {
// ...
}

 

 

 

✳️ 함수 자체에 타입 정해주기

const mall: { // 위에서 썼던 값들을 이 객체의 프로퍼티로 넣어줬다.
  stock: { [id: string]: number };
  cart: string[];
  addToCart: (id: string, quantity?: number) => boolean; // 화살표 함수와 비슷
} = {
  stock: {
    c001: 3,
    c002: 1,
  },
  cart: [],
  addToCart,
};

function addToCart(id: string, quantity?: number) {
  if (!quantity) quantity = 1;

  if (mall.stock[id] < quantity) {
    return false;
  }

  mall.stock[id] -= quantity;
  for (let i = 0; i < quantity; i++) {
    mall.cart.push(id);
  }

  return true;
}

 

 

✳️ Rest Parameter 문법을 쓰는 경우

id 를 여러개 받아 addToCart 를 실행하는 함수를 써보자.

레스트 파라미터이기 때문에 배열식으로 타입을 정해주면 된다.

function addManyToCart(...ids: string[]) {
  for (const id of ids) {
    addToCart(id);
  }
}

 

이제 함수 자체 타입을 지정하자.

const mall: {
  stock: { [id: string]: number };
  cart: string[];
  addToCart: (id: string, quantity?: number) => boolean;
  addManyToCart: (...ids: string[]) => void; // ** 여기
} = {
  stock: {
    c001: 3,
    c002: 1,
  },
  cart: [],
  addToCart,
  addManyToCart, // ** 여기
};

 

** addManyToCart 함수는 아무것도 리턴하지 않는데

이런 경우 return 값에 void 를 작성해 줘야 한다. 아무것도 리턴하지 않는 함수를 void 함수라 한다.

 

 

~ 활용 ~

function getDiff(fromPoint: [number, number], toPoint: [number, number]): [number, number] {
  let dx = toPoint[0] - fromPoint[0];
  let dy = toPoint[1] - fromPoint[1];
  return [dx, dy];
}

const monster: {
  name: string;
  level: number;
  hasGold?: boolean;
  skills: string[];
  move: (fromPoint: [number, number], toPoint: [number, number]) => void
} = {
  name: '고블린',
  level: 22,
  skills: ['태권도', '특공무술'],
  move(fromPoint, toPoint) {
    let [dx, dy] = getDiff(fromPoint, toPoint);
    console.log(`오른쪽으로 ${dx} 위쪽으로 ${dy} 만큼 이동!`);
  }
}

const current: [number, number] = [0, 0];
const target: [number, number] = [4, 5];
monster.move(current, target);

// 오른쪽으로 4 위쪽으로 5 만큼 이동!

 

 

 

 

'TypeScript' 카테고리의 다른 글

[TS] const 상수 리터럴 타입  (0) 2024.03.04
[TS] interface 인터페이스  (0) 2024.03.04
[TS] enum 열거형 타입  (1) 2024.03.04
[TS] 배열 & 튜플, 객체 & 옵셔널 프로퍼티  (0) 2024.03.04
[TS] 타입스크립트 시작하기  (0) 2024.03.04