타입스크립트에는 -Like
타입이 있다. Array
와 ArrayLike
, Promise
와 PromiseLike
-Like
postFix가 붙여진 타입이 왜 필요한지 알아보자.
Array
vs. ArrayLike
Array
lib.es2015.core.ts 파일에서는 Array
타입을 다음과 같이 정의하고 있다. 자주 사용하는 find
, fill
등의 메소드도 찾아볼 수 있다.
interface Array<T> {
/**
* Returns the value of the first element in the array where predicate is true, and undefined
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found, find
* immediately returns that element value. Otherwise, find returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
/**
* Returns the index of the first element in the array where predicate is true, and -1
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found,
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
/**
* Changes all array elements from `start` to `end` index to a static `value` and returns the modified array
* @param value value to fill array section with
* @param start index to start filling the array at. If start is negative, it is treated as
* length+start where length is the length of the array.
* @param end index to stop filling the array at. If end is negative, it is treated as
* length+end.
*/
fill(value: T, start?: number, end?: number): this;
/**
* Returns the this object after copying a section of the array identified by start and end
* to the same array starting at position target
* @param target If target is negative, it is treated as length+target where length is the
* length of the array.
* @param start If start is negative, it is treated as length+start. If end is negative, it
* is treated as length+end.
* @param end If not specified, length of the this object is used as its default value.
*/
copyWithin(target: number, start: number, end?: number): this;
}
ArrayLike
반면 lib.es5.d.ts 파일에서는 배열 길이 반환과 인덱스 기반 접근만 가능하다고 심플하게 ArrayLike
를 정의하고 있다.
interface ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
}
✅ 차이점
자바스크립트 언어에서는 배열과 유사하지만, 완벽한 배열은 아닌 유사 배열 객체
가 존재한다.
대표적으로 다음과 같은 상황에서 사용된다.
조금 더 넓은 의미로 배열 타입을 사용하여 유사 배열 객체까지 포함하는 타입이 필요하기 때문에 ArrayLike
를 추가했다고 볼 수 있다.
Promise vs. PromiseLike
Promise
Promise에는 나중에 finally
가 추가되어서 두 개의 파일을 살펴보아야 한다.
lib.es5.d.ts에는 then
과 catch
가 정리되어 있다.
/**
* Represents the completion of an asynchronous operation
*/
interface Promise<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
/**
* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
*/
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}
lib.es2018.promise.d.ts에서는 finally
가 추가되었다.
/**
* Represents the completion of an asynchronous operation
*/
interface Promise<T> {
/**
* Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
* resolved value cannot be modified from the callback.
* @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).
* @returns A Promise for the completion of the callback.
*/
finally(onfinally?: (() => void) | undefined | null): Promise<T>
}
PromiseLike
그런데 lib.es5.d.ts의 PromiseLike
를 보면 then
만 정의되어있다.
interface PromiseLike<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
}
✅ 차이점
PromiseLike
역시 ArrayLike
와 비슷하게 넓은 의미의 타입 적용을 가능하게 하려고 만든 타입이다.
처음 Promise
개념이 등장했을 때는 then
만 지원하는 라이브러리가 많았다고 한다. (bluebird, Promises/A+, jQuery 등등...)
그럴 수 밖에 없는게 then밖에 없었음😇
하지만 개발자의 필요에 의해 catch
와 finally
가 정식 문법으로 추가되면서Promise
타입은 정식 문법에 맞추어 then
, catch
, finally
를 모두 지원하는 타입으로,PromiseLike
는 과거 라이브러리들과의 호환성에 맞추어 then
만 지원하는 타입도 포함하도록 정의되었다고 볼 수 있다.
참고한 링크
'Frontend' 카테고리의 다른 글
자바스크립트 가비지 컬렉팅(GC) 어디까지 알고있나? (1) | 2023.12.15 |
---|---|
자바스크립트 V8 엔진의 메모리 구조와 사용 (0) | 2023.12.15 |
[타입챌린지/type-challenge] Flatten (0) | 2023.02.04 |