240327 인프런 타입스크립트 밋업 후기
posted by mia · 2024-03-27
인프런 타입스크립트 밋업 후기: 타입스크립트로 하는 함수형 프로그래밍 & 객체지향 FE 개발
최근 함수형 자바스크립트 프로그래밍의 저자이신 유인동 마플 CTO님의 인프런 타입스크립트 밋업에 다녀왔다. '타입스크립트와 함수형 프로그래밍 & 객체지향 FE 개발'이라는 주제로 진행된 이번 밋업은 함수형 프로그래밍의 관점에서 객체지향(Object-Oriented Programming, OOP)을 어떻게 바라보고 활용할 수 있는지에 대한 깊은 인사이트를 얻을 수 있는 소중한 시간이었다.
서론: 왜 다시 객체지향인가?
유인동 님은 2011~2013년 자바스크립트 생태계의 한계로 인해 라이브러리 의존적인 개발이 불가피했고, 이 시기에 등장한 리액트와 함수형 패러다임이 프론트엔드 개발의 대세가 되었다고 설명해 주셨다. 하지만 이제 웹 표준 기술이 성숙하고 타입스크립트가 현대적인 언어의 기능을 대부분 지원하게 되면서, 과거의 단점을 보완한 객체지향 프로그래밍을 다시금 잘 활용할 수 있는 시대가 열렸다고 말씀하셨다.
이번 세션은 웹 표준과 코어 기술을 중심으로, 유인동 님이 직접 만든 rune-ts
라는 라이브러리를 통해 타입스크립트 환경에서 어떻게 객체지향 프로그래밍을 효과적으로 구현할 수 있는지 보여주는 방식으로 진행되었다.
본론: 코드로 살펴보는 현대적 객체지향
1. rune-ts: 자바를 닮은 타입스크립트 코드
가장 먼저 눈에 띈 것은 rune-ts
를 활용한 코드 스타일이었다. override
키워드나 main()
메서드 등 마치 Java Spring 프레임워크를 연상시키는 구조는 신선한 충격이었다.
// Web API를 직접 활용하는 모습
this.element.classList.toggle();
this.element.dispatchEvent(new Event());
// 데코레이터를 활용한 이벤트 처리
@on('click', '.reset')
private _reset() {
// ...
}
또한 이처럼 프레임워크에 의존하기보다 웹 표준 API를 적극적으로 활용하고, 타입스크립트의 데코레이터 같은 최신 기능을 통해 코드의 가독성과 유지보수성을 높이는 점이 인상 깊었다.
2. 제네릭을 활용한 강력한 추상화
객체지향의 꽃이라 할 수 있는 추상화는 제네릭(Generic)을 통해 구현되었다. ListView
라는 추상 클래스를 만들어 공통 로직을 묶고, 이를 상속받는 SettingListView
에서 구체적인 타입을 지정해 재사용성을 극대화하는 예제는 무척 실용적이었다.
// 공통 컴포넌트 추상화를 위한 제네릭 활용
abstract class ListView<T extends object> extends View<T[]> {
itemViews = this.data.map((item: T) => this.createItemView(item));
abstract createItemView(item: T): IV;
override template() {
return `<div>${this.itemView}</div>`;
}
}
class SettingListView extends ListView<Setting, SettingItemView> {
override createItemView(item: Setting): SettingItemView {
return new SettingItemView(item);
}
}
이에 대한 질문으로 타입 추론 vs. 명시적 선언에 대한 논의도 있었는데, 유인동 님은 IDE가 타입을 잘 추론해준다면 유연성을 위해 추론에 맡기는 편이지만, 명시적으로 타입을 선언하면 의도치 않은 실수를 방지하여 안정성을 높이는 장점이 있다고 설명해 주셨다.
3. 상속, 신중하지만 강력하게
"상속은 조심스럽고 보수적으로 사용해야 한다"는 조언도 있었다. 특히 비즈니스 로직이 복잡하고 변경이 잦은 부분에서는 상속이 오히려 발목을 잡을 수 있기 때문이다. 클래스로 상속할 때는 명확할 때만 해야 된다고 하셨는데,
- 언제 상속을 사용해야 할까?
- 도메인 특수성이 적고, 재사용성이 명확할 때 (e.g.,
ListView
,ToggleView
) - 서버나 외부 데이터 의존성이 거의 없는 순수 UI 컴포넌트
- 도메인 특수성이 적고, 재사용성이 명확할 때 (e.g.,
복잡한 요구사항에서는 상속 대신 컴포지션(Composition) 을 활용하는 것이 더 나은 해결책이 될 수 있다.
컴포지션: 여러 부품(객체)을 조립하여 하나의 완성품(객체)을 만드는 관계 기반의 설계 기법
4. import type
의 의미
코드 중간에 import { type View } from 'rune-ts'
와 같은 구문이 있었다. 이는 일반 import
와 달리 타입 정보만을 가져오기 위해 사용 된다. 이렇게 하면 트랜스파일 시점에 해당 코드가 제거되어 번들 사이즈를 줄이는 효과를 얻을 수 있다. 타입스크립트 개발에서 유용하게 사용할 수 있는 팁이었다.
결론: 컴포넌트가 쌓일수록 리액티브해지는 객체지향
내가 생각한 이번 밋업의 핵심 메시지는 아래와 같다.
리액트가 프레임워크 차원에서 '리액티브'한 환경을 제공한다면, 잘 설계된 객체지향 프로그래밍은 컴포넌트가 쌓여갈수록 개발 경험 자체가 리액티브해진다.
초기에는 뷰를 다루는 코드를 작성하지만, 잘 만들어진 컴포넌트들이 쌓이면 개발자는 점차 데이터를 다루는 작업에만 집중하게 된다. 즉, 뷰와 로직이 자연스럽게 분리되고, 개발 속도는 오히려 가속화된다는 것이다. 이는 패러다임 자체가 주는 강력한 이점이라고 할 수 있다.
Q&A: 인상 깊었던 질문과 답변
- Q: 성급한 추상화를 피하는 방법은?
- A: 현업에서는 일단 컴포넌트를 크게 만드는 것이 낫다. 기획 변경에 유연하게 대응하고 빠르게 출시하는 것이 중요하기 때문이다. 중복이 발생했을 때 그 중복을 제거하는 방식으로 점진적으로 리팩토링하는 것을 추천한다. (마틴 파울러의 '리팩토링' 책의 핵심)
- Q: RxJS와 함수형 프로그래밍의 차이는?
- A: RxJS는 자체적인 에러 핸들링과 실행 모델을 가지기 때문에 단순한 라이브러리를 넘어 하나의 '언어'처럼 동작한다. 진정한 함수형 프로그래밍 라이브러리는 프로미스 반환, 언어 자체의 에러 핸들링 스코프 존중 등 기존 언어와 자연스럽게 통합되어야 한다고 생각한다.
- Q: 프론트엔드에도 아키텍처가 있는가?
- A: 아직 명확한 아키텍처가 정립되었다고 보기는 어렵다. 하지만
rune-ts
가 그 방향성을 제시하는 하나의 시도라고 생각한다. 모델(데이터)은 가급적 순수 JSON 객체처럼 다루어 사이드 이펙트를 최소화하고, 이는 함수형 패러다임으로 다루는 것이 유리하다.
- A: 아직 명확한 아키텍처가 정립되었다고 보기는 어렵다. 하지만
이번 밋업은 함수형 프로그래밍에 익숙하지 않았던 나에게 함수형 프로그래밍과 객체지향 패러다임의 새로운 가능성을 열어준 귀중한 시간이었다. 유인동 님께서 공유해주신 rune-ts
와 마플의 오픈소스 프로젝트를 살펴보며, 타입스크립트와 함께 더 나은 코드 구조를 고민해봐야겠다.