일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 가천대
- 알고리즘
- HTTP
- dp
- 문자열
- 타입스크립트
- 소켓
- BFS
- 백준
- socket
- 프로그래머스 레벨 2
- Algorithm
- 레벨 1
- TCP
- type challenge
- typescript
- Nestjs
- 그래프
- 크롤링
- Node.js
- 수학
- Crawling
- dfs
- 자바스크립트
- 쉬운 문제
- HTTP 완벽 가이드
- 타입 챌린지
- ip
- javascript
- 프로그래머스
- Today
- Total
목록전체 글 (499)
kakasoo
interface Person { body: number; mind: boolean; soul: boolean; } type Zombie = MyOmit; // type Zombie = { body: number }; Person에서 mind | soul을 제외하면 body만 남는 걸 Zombie라고 정의할 수 있다고 해보자. MyOmit은 방금 한 말을 타입으로 정의하는 방법으로, TypeScript에서 Utility type으로 이미 정의된 Omit과 동일하다. Omit 타입을 구현하려면 아래처럼 사고를 확장해나가면 된다. type MyOmit = any; 가장 먼저 이 타입은 두 개의 타입 파라미터를 받는다고 정의할 수 있다. type MyOmit = any; K는 무조건 T라는 타입 안에 정의된 ..
type Includes = T extends [infer P, ...infer R] ? // T가 P와 나머지 R로 이루어진 배열이라면, 즉 length가 최소한 1 이상인 경우라면 Equal extends true ? true : Includes // U가 P랑 같다면 true, 아니라면 Includes를 재귀적으로 호출한다. : false Includes에서 재귀적으로 호출해야 한다는 사실을 알기 전까지는 머리카락이 다 빠질 것만 같았다. 왜냐하면 boolean이나 객체와 같은 경우에는 단순히 그 값을 U extends T[number] 형식으로 비교할 수 없기 때문이다. true는 boolean에 포함된다.
type First = T['length'] extends 0 ? never : T[0]; type A = First; // 3 type B = First 123, { a: string }]>; // () => 123 type C = First; // never 어떤 배열 T에 대해 T의 length가 0일 경우에는 어떠한 값도 없어야 하기 때문에 never, 그 외의 경우에는 T의 0번째 값을 반환한다. 타입 치고는 배열을 다루기 때문인지 무척이나 간단한 형태를 띄고 있다.
Everyone does not report to everyone. Responsibilities and authorities are assigned to individuals based on assessments of their ability to handle them. People are given the authority that they need to achieve outcomes and are held accountable for their ability to produce them. At the same time, they are going to be stress-tested from both directions--i.e., by those they report to and by those w..
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: '이미지의 정렬 값이 동일한 경우가 존재합니다.' }, CANNOT_FINDONE_ARTICLE: { code: 4004, message: '게시글을 찾지 못했습니다.' }, SELECT_MORE_THAN_ONE_BODY_IM..
어떤 객체를 문자열로 변환한 것에 함수가 포함되어 있는 경우 JSON.parse는 사용할 수 없다. 이런 경우, 안타깝게도 정상적인 방법은 없다. 다만, 그나마 가능성이 있는 것이 바로 정규표현식으로, 아래와 같이 작성해볼 수 있다. const regex = /(?\s*\{[\s\S]+?\})\s*(?=,|})*/g; async가 있을 수도 없을 수도 있는 function 혹은 화살표 함수에 대한 정규 표현식으로, 이걸 사용해 함수 부분을 캐치한다. 그 후 String.prototype.replaceAll 로 함수 부분을 쓸 모 없는 아무 값으로 변환하는 것이다. 하지만 그나마 가능성 있다는 말처럼, 나는 이런 정규 표현식을 사용하여 문제를 해결하는 데에는 실패했다. 왜냐하면 내가 마주한 문제는 \r\n..
1. 데이터는 언제나 옳다. 데이터를 보고 아니라는 답이 나온다면, 아닌 것을, 억지로 하려고 하면 필연적으로 망할 뿐이다. 가끔 데이터를 제공해줘도 "아직 안 해봤잖아" 라는 말을 하는 사람들을 본다. 이런 이들은 직접 행하고, 물론 그것도 재능이겠지만, 하고 나면 필연적으로 망해 있는 것을 학습 비용으로 여긴다. 또 실패할 것을 염려하는 사람들을 시니컬한 사람으로 여긴다. "해봤어?" 라는 말로 성공 신화를 써내려간 전설적인 기업인도 있지만, 만약 그런 물음을 듣는다면 나는 해보진 않았지만 해본 것을 봤다 정도는 말할 수 있겠다. 2. 고객의 목소리를 듣는 것은 좋다. 비록 그게 데이터가 아니라서, 통찰을 정제해낼 수 없는 정보라고 하더라도, 듣는 행위 그 자체만으로도 고객에게 존중받는 느낌을 줄 수..
git rebase -i --root # 나의 경우 처음부터 다른 계정을 썼기 때문에 root부터, 그렇지 않다면 수정하고 싶은 커밋의 이전부터 수정하길 원하는 커밋 로그 앞의 pick을 edit으로 수정하면 수정 대상이 된다. 만약 수정할 내용이 많다면 아래를 참고한다. Vim은 문자열 대체(replace) 기능을 지원한다. 다음과 같은 명령어를 사용할 수 있다. :s/old/new - 현재 커서가 위치한 라인의 첫 번째 "old"를 "new"로 대체. :s/old/new/g - 현재 커서가 위치한 라인의 모든 "old"를 "new"로 대체. :%s/old/new/g - 현재 열린 파일의 모든 "old"를 "new"로 대체. :n,ms/old/new/g- n번째 라인부터 m번째 라인까지의 "old"를 ..
설치해야 하는 패키지 종류 $ 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개 정도 작성하면서, 라이브러리가 동작한다는 가정 하에 내가 원하는 코드를 짜봤어야 했다. 나 같은 경우에는 처음에 만든 패턴에서, 새로운 아이디어가 생각나서 초기 패턴과 다른 두 번째 패턴을 만들었다. 두 번째 패턴은 첫 번째 패턴보다 더 나은 패턴이다보니 첫 번째 패턴을 사용해야 할 이유가 사라지는 듯 했다. 물론 두 번째 패턴의 단점이 있었고, 첫 번째 패턴이 그보다 나은 점이 있었다. 하지만 더 고민해보니 두 패턴을 섞음으로써 얻을 수 있는 장점이 있어 보였다. 아, 이런. 조금 더 빨리 생각 했으면 좋았을 걸 이라는 생각 대신에, 설계에 더 오랜 시간을 들일 것을 다짐해야겠다. 주말에는 이 패턴들을 융합시키는 데에 시간을 써야 할 거 같다.