프로그래밍TypeScript 아키텍트

TypeScript에서 연산자 오버로딩을 어떻게 구현합니까? 직접적으로 가능한가요? 우회 방법은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

TypeScript는 연산자 오버로딩을 직접적으로 지원하지 않습니다. 오히려 기능/클래스 수준에서 이 동작을 모방할 수 있습니다. 자바스크립트(그리고 TypeScript의 JS 트랜스파일)에서는 사용자 정의 타입에 대해 표준 연산자(+, *, - 등)의 동작을 변경할 수 있는 기능을 제공하지 않습니다.

이 문제의 역사: C++이나 C# 같은 언어에서는 객체와 작업할 때 연산자에 대해 사용자 정의 동작을 설정할 수 있습니다. TypeScript(및 JavaScript)에는 그런 기능이 없으며, 결과적으로 생성되는 것은 전통적인 JS 코드로, 연산자가 내부 타입과 엄격하게 연결되어 있습니다.

문제: 추상 엔티티(예: 벡터, 행렬, 금액 등)로 구성된 클래스를 개발할 때, 연산자를 통해 이들과의 편리한 작업이 필요할 때가 있습니다. TypeScript에는 이런 작업을 네이티브하게 수행할 수 있는 구문이 없습니다.

해결책: 연산자 오버로딩을 모방하기 위해 명확한 이름을 가진 메소드를 생성합니다(add, mul, sub 등). 경우에 따라 정적 메소드나 유틸리티 함수를 사용하는 것도 있습니다. 또한, valueOf 메소드를 통해 명시적 타입 변환을 구현할 수도 있지만, 이는 모든 연산자의 완전한 오버로딩에는 부족하며, 원시 값에 대해서만 일부 연산자에 대해 작동합니다.

코드 예시:

class Vector2D { constructor(public x: number, public y: number) {} add(v: Vector2D): Vector2D { return new Vector2D(this.x + v.x, this.y + v.y); } } const v1 = new Vector2D(1, 2); const v2 = new Vector2D(3, 4); const result = v1.add(v2); // Vector2D { x: 4, y: 6 }

주요 특징:

  • 내장된 연산자 오버로딩 지원 없음
  • 명시적 메소드 사용(add, sub)
  • valueOf 메소드는 일부 연산자에 대해서만 제한적으로 작동함

속임수 질문들.

valueOf/toString을 정의하면, 클래스에 대해 + 연산자가 작동할까요?

아니요. valueOf는 원시 타입으로의 변환 시 행동에만 영향을 미칩니다. + 연산자에서는 예기치 않은 결과를 초래할 수 있으며, 나머지 연산자는 설정할 수 없습니다.

class Currency { constructor(private amount: number) {} valueOf() { return this.amount; } } const c1 = new Currency(10); const c2 = new Currency(5); console.log(c1 + c2); // 15, 그러나 이는 Currency 객체가 아닙니다!

TypeScript에서 Proxy를 사용하여 연산자를 오버로딩할 수 있나요?

아니요. Proxy는 속성과 메소드 접근을 가로챌 수 있지만, 연산자(+, * 등)의 작동은 변별할 수 없습니다. 그들은 내장된 타입에서만 작동합니다.

인터페이스나 타입에서 선언을 통해 연산자를 "오버로딩"할 수 있나요?

아니요. 인터페이스에서는 메소드와 함수 시그니처만 설명할 수 있으며, C#처럼 연산자 오버로딩을 설명할 수는 없습니다(예: operator+).

일반적인 오류 및 안티 패턴

  • operator+(a, b) 형태의 함수를 쓰려고 시도하고 그에 대해 기대함
  • 비즈니스 로직 구현에 valueOf 사용하기 (valueOf шаблон 메소드는 코드를 암시적으로 만듭니다)
  • 하나의 클래스에서 원시값의 대체와 클래스 로직 결합하기

실생활 예시

부정적인 케이스

개발자가 Currency 클래스에 valueOf를 추가하여 숫자 표현을 얻고 직접적으로 수학 연산을 수행하려 했습니다(currency1 + currency2). 그 결과 의미가 상실되었습니다. 덧셈 결과는 단순한 숫자가 되었고, 화폐 객체가 아니기 때문에 반환되는 값의 타입을 추적할 수 없었습니다.

장점:

  • 간결한 표현 (currency1 + currency2)
  • 기본 작업에서 코드 양 감소

단점:

  • 타입 안전성 상실
  • 반환 객체 제어 불가
  • 복잡한 디버깅

긍정적인 케이스

Vector 클래스에서 새로운 벡터를 반환하는 add 메소드가 구현되었습니다. 명확하게 타입화되어 있으며, 애매함이 없습니다.

장점:

  • 엄격한 타입화
  • 작업 안전성
  • 유지 보수가 쉬움

단점:

  • v1 + v2를 쓸 수 없고, 오직 v1.add(v2)만 가능
  • operator overloading이 있는 언어에 비해 약간 더 장황한 표현