전체 글

배우고 성찰한 것을 기록하는 블로그입니다.
Typescript

재귀로 객체 내 모든 키값을 추출하는 타입 만들기

재귀로 객체 내 모든 키값을 추출하는 타입 만들기 객체 내 모든 키를 추출할 수 있는 타입을 만든 후, 컴포넌트에 적용하여 컴포넌트가 props로 받는 객체의 타입을 스스로 추론하게 만들어보자. 객체 재귀 타입(PropertyPath) 구현 type PropertyPath = U['length'] extends 10 ? never : { [K in keyof T & string]: T[K] extends Record ? K | `${K}.${PropertyPath}` : K }[keyof T & string] 위의 PropertyPath 타입은 객체의 모든 키를 추출하는 타입이다. 원활한 이해를 위해 몇가지 사전 ..

개발 일지

VSCode에서 소스 코드 저장 시 eslint + prettier가 동작하지 않는 경우

소스코드 저장 시 eslint + prettier가 자동으로 동작하지 않을 때가 있다. 이는 VSCode의 settings.json에서 eslint와 prettier 관련 설정을 고쳐주면 해결된다. { // ... "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "editor.formatOnSave": true // ... } 위 설정이 VSCode가 인지할 수 있는 eslint + prettier 설정이다. settings.json을 잘 컨트롤 하면 방금 실행한 설정 외에도 다채로운 설정을 할 수 있다. 전역설정 전역설정을 하려면 windows 운영체제 기준 C:\Users\유저명\AppData\Roaming\Code\User\s..

개발 일지

프로젝트 설계 이모저모 - 프론트엔드 리포지토리 패턴 구현

리포지토리 패턴 유지보수가 쉬운 코드 구조를 구현하는 방법은 제각각이지만 추구하려는 목표는 '코드의 응집도 증가와 결합도 감소'로 대부분 같다. 이를 위해서는 복잡한 로직을 가진 코드 뭉텅이를 여러 개의 레이어나 클래스로 분리하는 작업이 필연적일 수 밖에 없다. 아래 그림을 보자. A는 복잡한 로직이 하나의 레이어에 뭉쳐있는 것을 표현한 것이고 B는 복잡한 기능들을 레이어로 나눠놓은 것이다. A의 경우, 간단한 코드를 작성할 때 유리한 방식이다. 그러나 본질적으로 코드의 결합도가 높을 수밖에 없으므로 복잡한 기능을 구현해야할 때나 기능이 점차적으로 스케일업 되어야 하는 경우에는 작업량에 따라 수많은 에러와 유지보수 비용 증가가 발생할 것이다. B의 경우, 간단한 코드를 작성함에 있어서 사실상 시간적인 손..

개발 일지

Nextjs 프로젝트 설계 이모저모 - 과도기적 디렉토리 설계

사상누각 사상누각이라는 말이 있다. 모래위의 집이라는 말로써, 튼튼한 기초와 뼈대가 있어야 추후에 무너지지 않는다는 뜻이다. 이 말은 우리의 삶 어디에서나 통용될 수 있는 말 같다. 공부도 그렇고, 운동도 그렇다. 그리고 프로그래밍 또한 그렇다. 사실 프로그래밍만큼 사상누각이라는 말이 잘 어울리는 분야는 잘 없을 것 같다는 생각이 들 정도로 프로그래밍은 튼튼한 기초와 뼈대가 무엇보다 절실한 것 같이 보인다. 굉장히 작게 설계된 프로젝트가 나중에 살이 하나씩 붙더니 이내 거대해져서 관리가 어려워지는 경우가 발생했다고 가정해보자. 작은 사이즈의 프로젝트가 왜 어느순간에 엄청나게 비대해졌을까? 이는 아마도 프로그래밍이 논리적 작업이라는 특성 때문에 그런게 아닐까 싶다. 프로그래밍에는 물리적인 제약이 없어 개발..

개발 일지

Nextjs 프로젝트 설계 이모저모 - 집합적 사고로 레이아웃 설계하기

설계?유지보수 잘 하려면 코드를 이쁘게 짜 놓아야 한다. 하지만 코드를 이쁘게 짜겠다는 선언만으로는 그렇게 할 수 없다. 건물을 지으려면 땅에 줄부터 그어놔야 하듯이 코드가 올라갈 기반도 뭔가 틀이 잘 잡혀야 코드를 깔끔하게 올릴 수 있는데 이번 시리즈에서는 설계를 위한 다양한 시도 끝에 내가 얼추 픽스하려고 하는 것들을 남겨보려고 한다. Nextjs의 레이아웃나는 레이아웃의 설계가 상당히 중요하다고 생각한다. 컴포넌트가 어디에 배치되고 어디에 표시될지 명확하게 설계가 되어야 앞으로 올릴 컴포넌트들을 블록 쌓듯이 착착착 올릴 수 있기 때문이다. 그런 점에서 Next.js에서 제공하는 레이아웃은 기능별, 페이지별 분리가 너무나도 편하게 설계가 되어있어 사용하기 편하다. 레이아웃에 대한 Next.js의 공식..

Javascript

클래스) 자바스크립트 클래스 의존성 주입

의존성 주입 의존성 주입은 소프트웨어 개발에서 객체지향 설계 원칙과 디자인 패턴에 기반을 둔 개념이다. 등장배경 소프트웨어 개발에서 클래스들간의 결합도를 낮추고 유지보수성과 재사용성을 향상시키는 것은 중요한 목표이며, 의존성 주입은 이러한 목표를 달성하기 위해 등장한 디자인 패턴 중 하나이다. 의존성 주입 개념이 등장하기 이전에는 클래스가 직접 의존하는 객체를 클래스 내부에 생성하는 방식으로 의존성을 처리했다. 이는 클래스와 의존하는 객체 사이의 결합도를 높여 코드의 유연성과 테스트 용이성을 저해하는 문제점이 있었다. 이에 의존성 주입 개념이 등장하여, 클래스가 의존하는 객체를 외부로부터 주입받는 방식으로 의존성 문제를 해결하고, 클래스간의 결합도를 낮추게 되었다. 장점 유연성 : 의존성 주입을 사용하면..

C, C++

C++) 복사 생성자

복사 생성자 복사 생성자는 객체의 사본을 생성할 때 자동으로 호출되는 생성자 함수이다. 매개변수로 인스턴스의 포인터를 넘겨주어야하며, 이는 복사본의 원본 인스턴스에 대한 참조에 의해 쓰인다. #include using namespace std; class MyData { public: MyData() { // 디폴트 생성자 default constructor cout

C, C++

C++) 정적 멤버 static

정적 멤버 클래스 내 전역 변수나 전역 함수와 동일한 역할을 하는 클래스의 멤버로써 접두어로 static을 붙여서 선언한다. 클래스 자체에 내장되어 있으므로 인스턴스의 선언 없이 호출이 가능하고, 인스턴스의 선언 자체가 필요 없으므로 this를 이용해 참조할 수 없다. (애초에 인스턴스에 있는게 아니니까) #include class Test { public: Test(int data) : nData(data) { nCount++; } // Test 클래스로 인스턴스를 생성하면 nCount가 증가함. int getData() { return this->nData; } // 인스턴스 멤버 static int getCount() { return nCount; // nData에 접근할 수 없음. } // 정적 ..

C, C++

C++) 생성자 다중 정의 및 생성자 위임

생성자 다중 정의 클래스 생성자는 다중정의가 된다. class MyData { public: MyData(int nParam): nData(nParam){} MyData(int x, int y): nData(x + y){} void printData() { std::cout x = x; } MyPoint(int x, int y): MyPoint(x) { if (y > 200) y = 200; this->y = y; } void printCoord() { std::cout

C, C++

C++) 디폴트 생성자와 카피 생성자(참조자 멤버 초기화)

디폴트 생성자 디폴트 생성자는 클래스가 선언되었을 때 자동으로 호출되어 클래스의 멤버를 구성해주는 함수이다. 디폴트 생성자의 경우에는 클래스를 선언할 때 매개변수에 특정값을 넣을 필요가 없으므로, 이 점에서 다른 생성자들과 차이점이 있다. (매개변수 없이 알아서 호출되는 함수이기 때문) 사실 말만 복잡한 것이다. 단순히 디폴트 생성자를 사용한다는 것은 생성자를 명시하지 않아도 좋다는 것이며, 선언 시점에 매개변수를 넘길 필요가 없다는 뜻이기도 하다. class DefaultConstructor { public: DefaultConstructor():str1("디폴트"), str2("생성자") {} //또는 아래와 같이 선언 //DefaultConstructor() { //str1 = 30; //str2 ..

2DC
2DC