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+).
개발자가 Currency 클래스에 valueOf를 추가하여 숫자 표현을 얻고 직접적으로 수학 연산을 수행하려 했습니다(currency1 + currency2). 그 결과 의미가 상실되었습니다. 덧셈 결과는 단순한 숫자가 되었고, 화폐 객체가 아니기 때문에 반환되는 값의 타입을 추적할 수 없었습니다.
장점:
단점:
Vector 클래스에서 새로운 벡터를 반환하는 add 메소드가 구현되었습니다. 명확하게 타입화되어 있으며, 애매함이 없습니다.
장점:
단점: