티스토리 뷰

TypeScript for Java/C# Programmers

TypeScriptJava와 같이 정적 타이핑을 사용하는 언어에 익숙한 프로그래머들에게 인기 있는 선택이다.

TypeScript의 타입 시스템은 더 나은 코드 완성, 오류의 조기 발견, 프로그램 부분 간의 더 명확한 통신과 같이 정적 타이핑이 가지는 많은 이점을 제공한다. JavaScript(또한 TypeScript도 마찬가지로)가 기존의 객체 지향 프로그래밍(OOP) 언어와 어떤 차이가 있는지 다시 살펴볼 필요가 있다.

클래스 다시 생각하기 (Rethinking the Class)

C#Java는 의무적 OOP 언어라고 부릅니다. 이러한 언어에서 클래스는 코드 구성의 기본 단위일 뿐만 아니라 런타임 시 모든 데이터 그리고 동작의 기본적인 컨테이너이다. 기능과 데이터를 전부 클래스에 담도록 강제하는 것은 일부 문제에 대해선 좋은 도메인 모델이 될 수 있지만, 모든 도메인이 이러한 방식으로 표현될 필요는 없다.

정적 클래스 (Static Classes)

C#Java의 싱글턴과 정적 클래스 같은 특정 구조는 TypeScript에서 필요하지 않다.

TypeScript의 OOP (OOP in TypeScript)

원한다면 계속 클래스를 사용해도 된다! 일부 문제는 기존의 OOP 계층으로 해결하기 적합하며, TypeScriptJavaScript의 클래스를 지원하므로 이러한 모델을 더 효과적으로 만듭니다. TypeScript는 인터페이스, 상속, 정적 메서드 구현과 같은 많은 일반적인 패턴을 지원한다.

타입 다시 생각하기 (Rethinking Types)

TypeScript의 타입에 대한 이해는 사실 C#이나 Java와 상당히 다릅니다. 몇 가지 차이점을 살펴보자.

이름으로 구체화된 타입 시스템 (Nominal Reified Type Systems)

C#Java에서 주어진 값과 객체는 null, 원시 타입, 또는 정의된 클래스 타입 중 정확하게 하나의 타입을 가진다. 런타임 시점에서 정확한 타입을 묻기 위해 value.GetType() 또는 value.getClass()와 같은 메서드를 호출할 수 있다. 이러한 타입의 정의는 특정한 이름을 갖고 클래스의 어딘가 존재하며, 명시적인 상속관계나 공통적으로 구현된 인터페이스가 없는 이상 두 클래스가 유사한 형태를 가졌다 해도 서로 대체하여 사용할 수 없다.

이러한 양상은 reified, nominal 타입 시스템을 설명한다. 코드에서 사용한 타입은 런타임 시점에 존재하며, 타입은 구조가 아닌 선언을 통해 연관 지어진다.

집합으로서의 타입 (Types as Sets)

C# 또는 Java에서 런타임 타입과 해당 컴파일 타임 선언 사이의 일대일 대응관계는 중요하다.

TypeScript에서 타입은 공통의 무언가를 공유하는 값의 집합으로 생각하는 것이 좋다. 타입은 집합에 불과하기 때문에, 특정한 값은 동시에 수많은 집합에 속할 수 있다.

일단 타입을 집합으로 생각하기 시작하면, 특정 연산이 매우 자연스러워진다. 예를 들어, C#에서는 ‘string’과 ‘int’ 둘 다 가능한 타입이 존재하지 않기 때문에 이 값을 인자로 전달하는 것은 이상한다.

TypeScript에서 모든 타입이 단순히 집합이라는 것을 깨닫는 순간 이는 매우 자연스러워진다. ‘string’ 집합 또는 ‘number’ 집합에 속할 수 있는 값을 어떻게 설명하시겠까? 이 값은 단순히 그 집합들의 유니언: ‘string | number’에 속한다.

TypeScript는 집합론에 의거해 타입을 이용하는 여러 방법을 제공하며, 타입을 집합으로 생각하는 것이 더 직관적이다.

삭제된 구조적 타입 (Erased Structural Types)

TypeScript에서, 객체는 정확히 단일 타입이 아닙니다. 예를 들어 인터페이스를 만족하는 객체를 생성할 때, 둘 사이의 선언적인 관계가 없더라도 해당 인터페이스가 예상되는 곳에 해당 객체를 사용할 수 있다.

interface Pointlike { 
    x: number; 
    y: number; 
} 
interface Named { 
    name: string; 
}
 function printPoint(point: Pointlike) {
     console.log("x = " + point.x + ", y = " + point.y); 
} 
function printName(x: Named) { 
    console.log("Hello, " + x.name); 
} 
const obj = { 
    x: 0, 
    y: 0, 
    name: "Origin", 
}; 
printPoint(obj); 
printName(obj);

TypeScript의 타입 시스템은 명목이 아닌 구조적이다:

obj는 숫자인 x와 y 프로퍼티를 가지고 있으므로, Pointlike로서 사용될 수 있다. 타입 간의 관계는 특정 관계로 선언되었는지가 아닌, 포함된 프로퍼티에 의해 결정된다.

TypeScript의 타입 시스템은 또한 구체화되지 않았다:

런타임에 obj가 Pointlike임을 알려주지 않는다. 사실, Pointlike 타입은 런타임에 어떤 형태로도 존재하지 않는다.

집합으로서의 타입 개념으로 보면, obj를 Pointlike 값 집합이나 Named 값 집합의 멤버로 간주할 수 있다.

구조적 타입화의 결과 (Consequences of Structural Typing)

객체지향 프로그래머는 종종 구조적 타입화의 두 가지 측면에 놀라곤 한다.

빈 타입 (Empty Types)

첫 번째로 빈 타입은 예상을 무시하는 것처럼 보인다:

class Empty {} 
function fn(arg: Empty) {
     // 무엇인가를 하나요? 
} 
// 오류는 없지만, 'Empty' 타입은 아니지 않나요? 
fn({ k: 10});

TypeScript는 주어진 인수가 유효한 Empty인지 확인하여 fn의 호출이 유효한지를 검사한다 { k: 10 }class Empty { }의 구조를 확인하여 유효성을 검사한다. Empty에 프로퍼티가 없으므로 Empty가 수행하는 모든 프로퍼티가 { k: 10 }에 속해있다. 그러므로, 유효한 호출이다:

놀랍지만, 최종적으로 명목적인 객체지향프로그래밍 언어와 매우 비슷하게 사용된다. 파생 클래스와 파생 클래스의 기본 사이의 자연스러운 하위 타입 관계가 파괴되기 때문에, 하위 클래스는 삭제할 수 없다. 구조적 타입 시스템은 호환 가능한 유형의 속성을 갖는 측면에서 하위 타입을 설명하므로 위의 관계를 암시적으로 구별한다

동일한 타입 (Identical Types)

또 다른 빈번한 놀라움의 원인은 동일한 타입에 기인한다:

class Car {

drive() {

// hit the gas

}

}

class Golfer {

drive() {

// hit the ball far

}

}

// No error?

let w: Car = new Golfer();

다시 말하지만, 오류가 아닌 이유는 클래스의 구조가 동일하기 때문이다. 잠재적인 혼란의 이유가 될 수도 있겠지만, 사실 상관없는 클래스가 동일한 경우는 일반적이지 않다.

반영 (Reflection)

객체지향 프로그래머는 제네릭을 포함하여 어떤 값의 유형이라도 다룰(query)수 있음에 익숙하다.

// `C#`

static void PrintType<T\>() {

Console.WriteLine(typeof(T).Name);

}

TypeScript의 타입 시스템이 완벽히 지워졌으므로, 제네릭 타입 인자의 인스턴스화와 같은 정보는 런타임에 사용할 수 없다.

JavaScript에는 typeof와 instanceof와 같은 제한된 원시요소가 있지만, 이런 연산자는 타입이 지워진 코드의 출력에 존재하므로 여전히 작동함을 알아야 한다. 예를 들어, typeof (new Car())Car나 "Car"가 아닌 "object"이다.

Ref . https://www.typescriptlang.org/ko/docs/handbook/typescript-in-5-minutes-oop.html

'코딩 > TypeScript' 카테고리의 다른 글

TypeScript 004. tsc: TypeScript 컴파일러  (0) 2022.03.17
TypeScript 003. TypeScript 작성  (0) 2022.03.16
TypeScript 001. JavaScript와 TypeScript  (1) 2022.03.15
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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
글 보관함