티스토리 뷰

🤖 map 메소드 타입 정하기

map

원본 배열의 각 요소에 콜백함수를 수행하고 반환된 값들을 모아 새로운 배열로 만들어 반환한다.

const arr = [1, 2, 3];
let newArr = arr.map((el) => el*2); // [2, 4, 6]

map에 ctrl(또는 command)카를 누른 상태로 클릭을 하면 배열에 관련된 메소드가 정의되어 있는 파일이 열린다.

map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];

 

콜백 함수의 타입은 함수 타입 표현식으로 정의되어 있는 복잡한 모습이다.

 

이를 직접 구현해보자.

 

🤖 map 메소드 직접 만들기

1. 제네릭 함수가 아닌 일반적인 함수 만들기

function map(arr: unknown[], callback: (item: unknown) => unknown): unknown[] {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i]));
  }
  return result;
}

함수 map은 메소드를 적용할 배열을 매개변수 arr로 받고, 콜백 함수를 매개변수 callback으로 받는다.

  • map 메소드는 모든 타입의 배열에 적용해야 하기 때문에 arr 타입은 unknown[]로 정의한다.
  • callback 타입은 배열 요소 하나를 매개변수로 받아 특정 값을 반환하는 함수로 함수 타입 표현식을 사용해 정의한다.
  • map 메소드의 반환값은 배열 타입으로 정의한다.

 

 

2. 제네릭 함수로 만들기

모든 unknown타입을 타입 변수 T로 대체한다.

function map<T>(arr: T[], callback: (item: T) => T): T[] {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i]));
  }
  return result;
}

 

 

 

3. 함수 호출하기

const arr = [1, 2, 3];

function map<T>(arr: T[], callback: (item: T) => T): T[] {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(callback(arr[i]));
  }
  return result;
}

map(arr, (it)=>it*2); // it -> number 타입
// [2, 4, 6]
map(['hi', 'hello'], (it)=> it.toUpperCase()); // it -> string 타입
// ['HI', 'HELLO']

map(['123', '45'], (it)=> parseInt(it)); // ❌

여기서 함수 호출을 할 때 마지막 코드에서만 오류가 발생한 이유는 무엇일까?

 

앞선 코드에서는 인수의 타입과 반환값 타입이 모두 같다.

하지만 마지막 코드에서는 string[] 타입의 인수가 들어가지만 parseInt() 메소드는 문자열을 숫자 타입으로 변환하기 때문에 반환값의 타입은 string[] 타입이 아닌 number[] 타입이 된다.

 

map 메소드는 원본 배열의 타입과 다른 타입의 배열로도 변환할 수 있어야 한다. 따라서 타입 변수를 하나 추가한다.

// 반환값의 타입이 인수의 타입과 다른 배열의 반환도 가능해야 함
// -> 타입 변수 2개 사용하기
function map<T, U>(arr: T[], callback: (item: T) => U){
    let result = [];
    for(let i=0; i<arr.length; i++){
        result.push(callback(arr[i]));
    }
    return result;
}

map(['123', '45'], (it)=> parseInt(it)); // [123, 45]

 

 

 

 

 

 

 


🤖 forEach 메소드 타입 정하기

forEach

배열의 모든 요소에 콜백함수를 한 번씩 수행해주는 메소드이다.

forEach 메소드 또한 이미 정의되어 있는 메소드이다.

forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;

 

forEach 메소드를 직접 구현해보자.

 

🤖 forEach 메소드 직접 만들기

1. 일반적인 함수 만들기

// forEach 메소드 구현하기
// 콜백함수가 반환하는 값이 없으므로 void 타입으로 정의해도o
function forEach(arr: unknown, callback: (item: unknown) => void){
    for(let i=0; i<arr.length; i++){
        callback(arr[i]);
    };
};

 

map과 동일하게 2개의 매개변수를 받는다.

  • 순회 대상 배열을 매개변수 arr에 받는다.
  • 매개변수 callback에는 모든 배열 요소에 수행할 함수를 받는다. 

이때 forEach 메소드는 콜백함수가 반환하는 값이 없는 메소드이므로 콜백함수의 반환값 타입을 void로 정의한다.

 

 

 

 

2. 제네릭 함수로 만들기

타입 변수 T를 이용한다.

function forEach<T>(arr: T[], callback: (item: T) => void){
    for(let i=0; i<arr.length; i++){
        callback(arr[i]);
    };
};

 

 

 

 

 

3. 함수 호출하기

function forEach<T>(arr: T[], callback: (item: T) => void){
    for(let i=0; i<arr.length; i++){
        callback(arr[i]);
    };
};

forEach(arr2, (it) => console.log(it.toFixed())); // it -> number 타입
forEach(['123', '456'], (it) => console.log(it)); // it -> string 타입

각각 넘겨준 인자의 타입에 따라 반환값의 타입이 결정된다. 

 

 

 

 

 

 


🔗 타입스크립트 강의

 

한 입 크기로 잘라먹는 타입스크립트(TypeScript) - 인프런 | 강의

문법을 넘어 동작 원리와 개념 이해까지 배워도 배워도 헷갈리는 타입스크립트 이제 제대로 배워보세요! 여러분을 타입스크립트 마법사🧙🏻‍♀️로 만들어드립니다., 프론트엔드의 피할 수

www.inflearn.com

 

728x90