일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SSR
- 인터섹션
- map
- 무한 스크롤
- autosize
- async/await
- 리터럴 타입
- TS
- app router
- 반공변성
- 투포인터
- 타입 좁히기
- 이분 검색
- RTK Query
- Jest
- Promise
- 결정 알고리즘
- tailwind
- Cypress
- 호이스팅
- useAppDispatch
- ESlint
- 공변성
- React
- CORS
- 태그된 유니온
- webpack
- recoil
- CI/CD
- dfs
- Today
- Total
목록TS (34)
짧은코딩
재귀 타입 TS에는 자기 자신을 다시 사용하는 재귀 타입이 있다. type Recursive = { name: string; children: Recursive[]; }; const recur1: Recursive = { name: 'test', children: [{ name: 'test2', children: [] }], }; 이렇게 recur1은 Recursive 객체 속성 타입으로 다시 Recursive를 사용한다. 이런 것을 바로 재귀 타입이라고 부른다. -컨디셔널 타입 type ElementType = T extends any[] ? ElementType : T; 이런식으로 컨디셔널 타입에서도 사용 가능하다. 다만, 이렇게 재귀 타입을 잘못 사용하면 자기 자신을 계속 가져오는 상황에 빠질 수 ..
브랜드 속성 브랜드 속성은 객체를 구별할 수 있는 속성을 하나 추가하는 방법이다. 예시 interface Money { __type: 'money'; amount: number; unit: string; } interface Liter { __type: 'liter'; amount: number; unit: string; } 이 코드에서는 "__type" 이 속성을 브랜드 속성이라고 한다. 속성 이름은 다른 속성과 겹치지 않는 이름이면 다 가능하다. 이렇게 브랜드 속성을 사용하는 것을 브랜딩이라고 한다. 타입 좁히기 TS에서 타입을 구분하는 것은 중요하다. 대부분은 TS가 자체적으로 코드를 파악해서 타입을 추론하는 제어 흐름 분석(Control Flow Analysis)을 한다. 하지만 제어 흐름 분석이..
infer란? infer로 타입 추론을 극한으로 활용할 수 있다. 컨디셔널 타입과 같이 사용할 수 있다. 컨디셔널 타입(Conditional Type)이란? type A1 = string; type B1 = A1 extends string ? number : boolean; // number type A2 = number; type B2 = A2 extends string ? number : boolean; // boolean 특정 타입 extends 다른 타입 ? 참일 때 타입 : 거짓일 때 타입 특정 타입이 다른 타입의 부분집합일 때 참이 된다. infer의 예시들 배열의 요소 타입을 얻고 싶은 경우 type El = T extends (infer E) [] ? E : never; type Str =..
어떤 함수는 다른 함수에 대입할 수 있는데, 대입이 불가능한 경우도 있다. 이를 제대로 이해하려면 공변성, 반공변성을 알아야 한다. 공변성: A->B일 때, T -> T 인 경우 반공변성: A->B일 때, T -> T인 경우 이변성: A->B일 때, T -> T도 되고 T -> T도 되는 경우 무공변성: A->B일 때, T -> T도 안 되고 T -> T도 안 되는 경우 TS는 기본적으로 공변성을 갖고 있지만, 함수의 매개변수는 반공변성을 갖는다! 그리고 TS Config에서 strict와 strictFunctionTypes가 모두 체크되어야 함수의 매개변수가 반공변성을 갖는다. 둘 다 체크되지 않으면 이변성을 갖는다. 반환값 a->b인 경우 function a(x: string): number { re..
오버로딩 사용이 필요한 경우 오버로딩은 호출할 수 있는 함수의 타입을 미리 여러 개 타이핑하는 기법이다. function add(x: string | number, y: string | number): string | number { return x + y; } add(1, 2); add('1', '2'); add('1', 2); add(1, '2'); x와 y가 같은 타입일 경우에만 함수를 실행시키고 싶었다면, 이 코드에서는 불가능하다. 서로 다른 타입이어도 코드가 동작할 수 있도록 구현되어 있다. 그렇기에 이런 경우에 오버로딩 기법을 사용할 수 있다. 오버로딩 예시 function add(x: number, y: number): number; function add(x: string, y: strin..
타입스크립트에는 자바스크립트에는 없던 연산자들이 있다. 처음 봤을 땐, 나름 쉬워 보여서 그냥 넘어갈 수도 있지만 타입스크립트를 지속적으로 사용하다 보면 은근히 헷갈릴 때가 있었다. 그렇기에 이 글을 통해 정리하고자 한다. 연산자 유니언(|): 유니언 타입은 OR의 역할을 한다. 즉, 합집합의 역할을 한다. 인터섹션(&): 인터섹션 연산자는 AND의 역할을 한다. 즉, 교집합의 역할을 한다. 공집합(never) type nev = string & number; // never 인터섹션 연산자를 이용하여 위 코드를 작성하면 nev의 타입은 never가 된다. 즉, 타입스크립트에서 가장 좁은 타입이다. 전체집합(unknown) 전체집합은 unknown이며, 타입스크립트에서 가장 넓은 타입이다. 대입 원칙 타..
string 타입의 범위는 매우 넓다. string을 타입으로 선언하려면 더 좁은 타입이 있는지 확인해봐야 한다. string을 남발한 설계 interface Album { artist: string title: string releaseDate: string // YYYY-MM-DD recordingType: string // E.g., "live" or "studio" } 이 코드처럼 모두 string으로 선언하면 엉뚱한 값을 넣어도 타입 체커를 통과한다. 이렇게 string 타입이 남용된 코드는 문자열을 남발(stringly typed)했다고 한다. 더 좋은 타입 모델링을 하기 위해서는 타입의 범위를 좁혀서 선언해야 한다. 타입을 좁힌 설계 type RecordingType = 'studio' | ..
유니온의 인터페이스보다는 인터페이스의 유니온을 지향하는 것이 좋다. 사실 앞 문장만 딱 보면 좀 헷갈릴 수 있다. 하지만 막상 코드를 보면 익숙할 것이다. 백터를 그리는 프로그램 작성 예제 유니온의 인터페이스 interface Layer { layout: FillLayout | LineLayout | PointLayout; paint: FillPaint | LinePaint | PointPaint; } 이 코드는 유니온의 인터페이스이다. layout은 모양이 그려지는 방법, 위치를 제어하고, paint는 선의 스타일을 제어한다. 두 속성은 Fill, Line, Point 3개 중 하나를 통일해서 가져야 한다. 하지만 layout은 FillLayout, paint는 LinePaint로 하면 에러가 나게 될..
타입만으로 어떤 변수가 null이 될 수 있는지 없는지를 표현하기는 어렵다. B에서 A의 값이 나오는 거면 A가 null이 될 수 없을 때 B도 null이 될 수 없다. 반대로 A가 null이 될 수 있으면 B도 null이 될 수 있다. 값이 전부 null이거나 전부 null이 아닌 경우로 구분해야 모델링하기 쉽다. 최댓값, 최솟값 예시 잘못된 코드 function extent(nums: number[]) { let min, max for (const num of nums) { if (!min) { min = num max = num } else { min = Math.min(min, num) max = Math.max(max, num) // ~~~ Argument of type 'number | und..
타입을 잘 설계하면 코드를 직관적으로 작성할 수 있다. 타입을 잘 설계하기 위해서는 유효한 상태만 표현할 수 있는 타입을 만들어야한다. 웹 애플리케이션 예시 문제점이 있는 코드 -페이지를 렌더링 해주는 함수 interface State { pageText: string isLoading: boolean error?: string } declare let currentPage: string function renderPage(state: State) { if (state.error) { return `Error! Unable to load ${currentPage}: ${state.error}` } else if (state.isLoading) { return `Loading ${currentPage}....