일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- TCP
- Crawling
- dfs
- Nestjs
- 프로그래머스
- 문자열
- type challenge
- 자바스크립트
- 알고리즘
- 타입 챌린지
- 레벨 1
- 크롤링
- socket
- HTTP
- 소켓
- 쉬운 문제
- Node.js
- javascript
- 가천대
- HTTP 완벽 가이드
- 프로그래머스 레벨 2
- 타입스크립트
- 백준
- ip
- dp
- BFS
- 수학
- typescript
- Algorithm
- 그래프
- Today
- Total
목록프로그래밍/TypeScript (65)
kakasoo
type LookUp1 = U['type'] extends T ? U : never; type LookUp2 = U extends { type : T } ? U : never; 타입스크립트에서는 타입 가드를 정의하기 위해서 각 인터페이스에 type이라는 프로퍼티로 미리 이름을 지정하기도 한다. 이 type이라는 키의 값이 'dog'이면 Dog 인터페이스고 'cat'이면 Cat 인터페이스라는 식이다. 따라서 LookUp 로 정의되는 어떤 타입에 대하여 type 이 T인 경우를 찾아주는 함수를 만들 수 있다. 이름에서 보다시피 마치 엑셀의 VLookUp처럼 동작하는 것이다. 하지만 위의 코드는 제대로 동작하지 않고, 둘 중 아래의 LookUp2만이 올바르게 동작한다. 왜 그럴까? // LookUp1 에서는..
// type Replace = S extends `${infer R}${From}${infer T}` ? `${R}${To}${T}` : S type Replace = From extends '' ? S : S extends `${infer R}${From}${infer T}` ? `${R}${To}${T}` : S; 처음에 정의한 타입으로는 From이 빈 문자일 경우에 제대로 동작하지 않았다. 그래서 Replace에는 From이 빈 문자일 경우에는 그대로 S를 리턴하도록 하는 구문을 추가했다. 이 타입은 `${infer R}${From}${infer T}`로 구성된 타입에서 From을 To로 바꾸는 타입이다. 굳이 T를 붙인 이유는, 이 타입의 초기 문자열 S가 'foobarbar'와 같이 동일한 단..
declare function PromiseAll(values: readonly [...T]): Promise 배열도 객체라고 생각하면 그 key들은 그 배열의 length까지의 숫자들로 이루어지게 되기 때문에 그 키에 대한 값을 Awaited로 감싼 객체로 정의한다.
type TrimLeft = S extends ` ${infer Rest}` | `\n${infer Rest}` | `\t${infer Rest}` ? TrimLeft : S; type TrimRight = S extends `${infer Rest} ` | `${infer Rest}\n` | `${infer Rest}\t` ? TrimRight : S; type Trim = TrimRight; TrimLeft, Right를 구현한 후 이를 합성하는 것이 훨씬 더 쉽다. 처음에는 쓸 데 없는 욕심에 Trim을 extends로 쭉 나열했는데 가독성만 나빠졌다.
type TrimRight = S extends `${infer Left} ` | `${infer Left}\n` | `${infer Left}\t` ? TrimRight : S; 이걸 풀고 나니 TrimLeft를 더 쉽게 풀 수 있었을 것 같다.
type TrimLeft = S extends `${infer R}${infer Rest}` ? R extends ' ' | '\n' | '\t' ? TrimLeft : S : ''; string이 `${infer R}${infer Rest}` 일 때, R은 첫번째 글자가 되고 Rest는 나머지 모든 글자가 된다. 따라서 R이 빈 문자일 경우에는 Rest를 다시 재귀적으로 TrimLeft로 호출해주면 된다. R이 빈 문자가 아닐 경우에는 TrimLeft할 게 없으니 종료 시점으로 보고 S를 리턴하면 된다. 만약 string이 `${infer R}${infer Rest}`의 형식이 아닐 경우는 빈 문자이기 때문에 빈 문자를 리턴하면 된다.
type Flatten = T extends [infer R, ...infer Rest] ? R extends any[] ? [...Flatten, ...Flatten] : [R, ...Flatten] : []; 배열인지 아닌지에 따라 재귀적으로 풀 것인지 결정하면 된다. 만약 T가 infer R과 infer Rest로 구성된 배열일 때, R이 배열인지 아닌지에 따라 재귀적으로 접근하면 된다. Rest는 나머지 요소들이기 때문에 무조건 배열이며 따라서 재귀적으로 접근하면 된다. 만약 T가 이러한 배열이 아닐 경우에는 빈 배열이 된다.
type DeepReadonly = { readonly [K in keyof T]: T[K] extends ((...args:any[]) => any) ? T[K] : T[K] extends Record ? DeepReadonly: T[K] extends Array ? DeepReadonly : T[K]; } 타입을 재귀적으로 정의해야 한다는 것은 간단하지만, 그럼에도 빨간 줄이 사라지지 않아서 조금 헤맸다. 타입추론된 결과를 보니 함수도 객체라서 문제가 생긴 걸 파악할 수 있었고, 따라서 맨 앞에 extends를 하나 더 추가해 함수를 처리했다. 결과적으로 extends가 3개가 되었는데 이게 좋은 코드일까? type DeepReadonly = keyof T extends never ? T : { re..
import * as ts from "typescript"; // TypeScript 파일을 읽어들입니다. const sourceFile = ts.createSourceFile( "example.ts", ` const num: number = 42; const str: string = "Hello, TypeScript!"; const bool: boolean = true; `, ts.ScriptTarget.Latest ); // 타입 체커를 생성합니다. const program = ts.createProgram({ rootNames: ["example.ts"], options: { target: ts.ScriptTarget.ES2015, module: ts.ModuleKind.CommonJS, }, })..
GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge Collection of TypeScript type challenges with online judge - GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge github.com type MyReturnType = T extends (...args:any[]) => infer R ? R : never; 어떤 타입 T를 정의할 때, 그 T에 대한 정의는 반드시 제너릭 쪽에 되어야 할 필요가 없다. 제..
[Feature request]type level equal operator · Issue #27024 · microsoft/TypeScript Search Terms Type System Equal Suggestion T1 == T2 Use Cases TypeScript type system is highly functional. Type level testing is required. However, we can not easily check type equivalence. I want a... github.com 글에서 Equals을 어떻게 설명하는지 나와있다. 다만, 완벽한 정의가 아니고, 대부분의 상황에 적합한 것이기 때문에 유틸리티 타입에 포함되지는 않는 것 같다. export type Equ..
import type { Equal, Expect } from '@type-challenges/utils' type X = Promise type Y = Promise type Z = Promise type Z1 = Promise type T = { then: (onfulfilled: (arg: number) => any) => any } type cases = [ Expect, Expect, Expect, Expect, Expect, ] // @ts-expect-error type error = MyAwaited type MyAwaited = T extends PromiseLike ? R : T; // NOTE : 여전히 에러가 나는 케이스 // Expect // Expect infer R을 이용해서,..