일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 코어 자바스크립트
- 제로초
- 2주 프로젝트
- 리액트
- 리덕스
- 코드스테이츠
- 손에 익히며 배우는 네트워크 첫걸음
- 정재남
- 리트코드
- 회고
- 토익
- 프로그래머스
- LeetCode
- 자바스크립트
- Async
- til
- SQL 고득점 Kit
- 알고리즘
- 타입스크립트
- 파이썬
- 렛츠기릿 자바스크립트
- javascript
- codestates
- 타임어택
- 백준
- 타입스크립트 올인원
- 4주 프로젝트
- programmers
- python
- js
Archives
- Today
- Total
Jerry
[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part2. lib.es5.d.ts 분석- (11) : forEach, map 제네릭 분석 본문
Front/Typescript
[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part2. lib.es5.d.ts 분석- (11) : forEach, map 제네릭 분석
juicyjerry 2024. 2. 29. 01:11반응형
forEach, map 제네릭 분석
어떻게 타입스크립트가 타입을 파악할 수 있을까? 프로그래밍에는 마법이 없다, 제네릭 덕분이다.
forEach
interface Array<T> {
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
}
// type A<T> =
// class A<T> {}
[1, 2, 3].forEach((item) => { console.log(item); }); // 1, 2, 3
['1', '2', '3'].forEach((item) => { console.log(item); }); // 1, 2, 3
[true, false, true].forEach((item) => { console.log(item); }); // 1, 2, 3
위치를 잘 파악해야한다
callbackfn: (value: T, index: number, array: T[]) => void가 (item) => { console.log(item); }와 같고
item이 value이다.
<T>가 매개변수 value의 T와 일치하니 "1, 2, 3"와 item이 같을 수 밖에 없다
value에 커서를 올려 추론된 value의 타입을 확인해보면, 입력한 값의 타입별 내용을 확인할 수 있다.
interface Array<T> {
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
}
// type A<T> =
// class A<T> {}
// interface에서 선언할 때는 모른다(<T>), 실행할 때 알 수 있다 -> <number> 라는 것으로 타입을 알 수 있다 -> 그러므로 제네릭으로 미리 엮어 놓는다.
// const a: number[] = [1, 2, 3];
const a: Array<number> = [1, 2, 3];
a.forEach((value) => { console.log(value); }); // 1, 2, 3
const b: Array<string> = [1, 2, 3];
['1', '2', '3'].forEach((value) => { console.log(value); }); // 1, 2, 3
const c: Array<boolean> = [1, 2, 3];
[true, false, true].forEach((value) => { console.log(value); }); // 1, 2, 3
const d: Array<boolean> = [1, 2, 3];
['123', 123, true].forEach((value) => { console.log(value); }); // 1, 2, 3
function add<T>(x: T, y: T) { return x; } // good
add<number>(1, 2); // 타입스크립트가 멍청해서 추론을 제대로 못 해줄 때, 직접 명시해주기도 한다
add('1', '2');
add(true, false);
// function add<T>(x: T, y: T) { return x; }에서 <T>: 제네릭, add<number>(1, 2);에서 <number>: 타입 파라미터, <number>add(1, 2);에서 <number>: 강제 변환 (위치 조심)
// 제네릭도 변환하면 사라짐
interface Array<T> {
every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[];
}
-> S extends T : S는 T 타입에 속할 수 있어야 한다, T타입에 부분집합이여야 한다
map
interface Array<T> {
// map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
map<U>(callbackfn, thisArg): string[]; // 줄였을 경우, 중간에 매개변수 타입핑이 들어거 헷갈려 보이는 것이다
}
const strings = [1, 2, 3].map((item) => item.toString()); // ['1', '2', '3'] string[]
직접 타입을 넣어봐서 어떻게 추론되는지 확인할 수 있다
interface Array<number> {
map<string>(callbackfn: (value: number, index: number, array: number[]) => string, thisArg?: any): string[];
}
반응형