일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준
- dp
- 레벨 1
- BFS
- 프로그래머스
- socket
- type challenge
- 그래프
- 타입 챌린지
- Node.js
- TCP
- 소켓
- typescript
- 쉬운 문제
- 알고리즘
- 문자열
- Algorithm
- javascript
- 자바스크립트
- Crawling
- 타입스크립트
- ip
- 크롤링
- 가천대
- Nestjs
- 수학
- HTTP 완벽 가이드
- dfs
- HTTP
- 프로그래머스 레벨 2
- Today
- Total
목록2023/01 (33)
kakasoo
설치해야 하는 패키지 종류 $ npm i aws-sdk/client-s3 # 3.259.0 $ npm i multer # ^1.4.3" $ npm i multer-s3 # ^3.0.1 $ npm i @types/multer-s3 --save-dev # ^.3.0.0 일단 필요한 package들을 install한다. s3 package들의 경우 업데이트를 하면서 기존의 버전이 호환되지 않는 경우가 줄곧 발생한다. 혹시 몰라 버전도 주석으로 달아놓았으니 호환이 되지 않으면 버전을 맞추던가, 아니면 명시된 버전으로 진행하면 된다. NestJS에서 클라이언트로부터 이미지 받기 @Post() async upload(@UploadedFiles() files: Express.MulterS3.File[]) { if (..
import { SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface'; export const ERROR = { ALREADY_CREATED_EMAIL: { code: 4001, message: '이미 생성된 이메일입니다.' }, NO_AUTH_TOKEN: { code: 4002, message: '인증이 필요합니다.' }, IS_SAME_POSITION: { code: 4003, message: '이미지의 정렬 값이 동일한 경우가 존재합니다.' }, } as const; type KeyOfError = keyof typeof ERROR; type ValueOfError = (typeof ERROR)[KeyOfError..
import { BadRequestException, ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { ERROR } from '@root/config/constant/error'; import { DecodedUserToken } from '@root/types'; @Injectable() export class JwtGuard extends AuthGuard('jwt') { handleRequest( err: any, user: any, info: any, context: ExecutionContext, status?: any, ): TUser { if (i..
설계를 완벽히 해야 했다. 테스트 코드를 100 ~ 200개 정도 작성하면서, 라이브러리가 동작한다는 가정 하에 내가 원하는 코드를 짜봤어야 했다. 나 같은 경우에는 처음에 만든 패턴에서, 새로운 아이디어가 생각나서 초기 패턴과 다른 두 번째 패턴을 만들었다. 두 번째 패턴은 첫 번째 패턴보다 더 나은 패턴이다보니 첫 번째 패턴을 사용해야 할 이유가 사라지는 듯 했다. 물론 두 번째 패턴의 단점이 있었고, 첫 번째 패턴이 그보다 나은 점이 있었다. 하지만 더 고민해보니 두 패턴을 섞음으로써 얻을 수 있는 장점이 있어 보였다. 아, 이런. 조금 더 빨리 생각 했으면 좋았을 걸 이라는 생각 대신에, 설계에 더 오랜 시간을 들일 것을 다짐해야겠다. 주말에는 이 패턴들을 융합시키는 데에 시간을 써야 할 거 같다.
// Question : Exclude type을 정의하라 type question = any; TypeScript Utility type인 Exclude의 정의를 보면 T extends U ? never : T 라는 매우 생소한 표현이 등장한다. 아니, Exclude는 두번째 타입 파라미터로 받은 U를 제외한 나머지 타입을 반환하는데 왜 never 혹은 T 라는 타입이 되는가? 아래의 순서를 따라가면 그 의미를 이해할 수 있다. // Answer : 아래와 같은 논리를 따라가볼 수 있다. // 'a' | 'b' | 'c' 라는 타입에서 'a'를 exclude 한다고 가정한다. type answer1 = 'b' | 'c'; type answer2 = never | 'b' | 'c'; 주석과 같이 'a' ..
interface Person { name: string; age: number; } type Partial = { [P in keyof T]?: T[P]; // P will be each key of T } type PersonPartial = Partial; // same as { name?: string; age?: number; } in키워드는 키 조합의 모든 항목을 반복하는 구문의 일부로 사용된다. 위에서 Partial type은 key of T 이므로 name, age 프로퍼티들이 될 것이고, 그것이 반복된 키-밸류의 객체 타입을 의미한다. 다만 그 키의 값이 ?: 연산자로 optional 하다고 알려주기 때문에 이름의 의미와 같이, Partial하게 정의된다. type TupleToObjec..
findOne({ from, include, lessThanEqual, moreThanEqual, }: { from: T; include: IncludeType; lessThanEqual: V; moreThanEqual: W; }): ExecutionComparison; findOne({ from, include, lessThanEqual, moreThanEqual, }: { from: T; include: IncludeType; lessThanEqual: V; moreThanEqual: W; }): ExecutionComparison; findOne({ from, lessThanEqual, moreThanEqual, }: { from: T; lessThanEqual: V; moreThanEqual: W..
function test(a:boolean) { return a ? 1 : 2; } const a = test(true); 이렇게 작성했을 경우 a의 타입은 1 | 2로 추론된다. function test(a: true): 1; function test(a: false): 2; function test(a: boolean): 1 | 2 { return a ? 1 : 2; } const a = test(true); 이렇게 작성하면 a의 타입은 1로 추론된다. 조건에 따른 a 타입을 추론하기 위해서는 단지 오버로딩을 이용하는 것만으로도 충분하다. 만약 분기 처리에 따라서, 또는 파라미터로 받은 a를 내부에서 호출하는 다른 메서드로 호출하는 등 추가적인 분기 처리가 생긴다면, 그만큼 더 많은 오버로딩을 작성함..
이 글에 나와 있는 Push Type은 이전 글에서 설명하고 있다. type NTuple = ? 타입 N 튜플은 타입 파라미터 N을 튜플의 크기로 하는 Tuple 타입을 의미한다. 두번째 파라미터로 받은 T는, 튜플에 포함되어 있어야 하는 값이 있는 경우, 값을 정의하기 위해 존재한다. 이 NTuple을 정의하려면 어떻게 해야 할까? type NTuple = ? 일단 N은 number를, T는 any[]를 확장해주어야 한다. T의 경우 기본 타입으로 빈 배열 ( 여기서는 튜플이라고 하는 게 정확하다 ) 을 받는다. 파라미터를 받았으니 이제 구현 부분이다. 구현을 위해서는 튜플 타입이 의미하는 게 무엇인지, 논리를 하나 씩 따져보는 것이 좋을 것이다. type NTuple = T['length'] exte..
타입스크립트에서 제너릭으로 받은 타입 T, P… 등등은 일반적으로 타입 파라미터라고 부른다. 그 이유는, 제너릭이 타입을 매개변수로 받아 타입에 따른 클래스와 함수를 정의하기 때문이다. 이렇게 제너릭을 활용하면 코드를 추상적으로 작성 가능해져 타입 별로 코드를 구현할 필요가 없게 된다. type Push = [...T, value]; 이 Push 라고 하는 타입은 T와 value 라는 타입 파라미터를 받는다. 이번에 구현할 Push 타입은 Array.prototype.push와 같이, 타입에 새로운 타입인 value를 확장하는 타입이다. 기존의 push 메서드는 push 연산 이후의 배열이 어떤 상태인지, 타입 레벨에서의 추론이 동작하지 않는다. 첫번째 타입 파라미터 T는 any[]를 확장하며, valu..
type Length = T['length']; 타입 레벨에서의 extends 키워드는 타입 상속을 의미한다. 타입 A가 B를 상속할 때, A는 B의 모든 프로퍼티와 메서드를 상속받아야 하는데, 조건문의 의미로도 쓰인다. A가 B를 상속받는다는 것은 최소한 A가 B와 같거나, B보다 더 구체적인 ( = 더 많은 프로퍼티를 가진 ) 것이다. 위의 Length는, 생각보다 별 거 아닌 게, 제너릭으로 받은 T는 any[]를 상속받으니 즉 어떠한 배열을 의미한다. T가 배열이라면 반드시 내부에 length 프로퍼티가 있기 때문에, T[’length’]로 특정 프로퍼티를 뽑을 수 있다. type Length = T['length']; type A = Length; const length: A = 5; // 5가..
// Extract type a = 'a'|'b'; type b = Extract // 'a' type c = Extract // 'a' | 'b' Type에서 Union에 할당할 수 있는 모든 Union 멤버를 추출하여 유형을 구성한다. 위 코드에서는 a 로부터 두번째 타입 인자로 받은 Union에 할당 가능한 대상을 각각 추출한 것이다. a로부터 ‘a’ 상수 타입에 들어갈 수 있는 것은 ‘a’ 상수 타입 뿐이며, string 타입에 들어갈 수 있는 건 ‘a’, ‘b’ 모두다.