(TS) Type Compatibility

Mirrer·2022년 12월 29일
0

TypeScript

목록 보기
12/14
post-thumbnail

Type Compatibility

Typescript 코드에서 특정 타입이 다른 타입에 잘 맞는지를 의미

타입호환(Type Compatibility)이란 Typescript 코드에서 특정타입이 다른 타입과 잘 호환되는지를 의미한다.

즉 타입 코드를 해석해나가는 과정에서 두개의 타입이 서로 호환이 되는지를 점검한다.

interface Developer {
  name: string;
}

class Person {
  name: string;
}

let i: Developer;
i = new Person(); // OK, because of structural typing

C#, Java...등에서는 Person 클래스가 명시적으로 Developer 인터페이스를 상속받아 구현하지 않았기 때문에 위와 같은 코드는 에러를 발생시킨다.

하지만 Typescript는 아래와 같은 Javascript 작동 방식과 유사하여 동작하여 에러를 발생시키지 않는다.

Javascript객체 리터럴, 익명 함수...등을 사용하기 때문에 명시적으로 타입을 지정하는 것보다 코드의 구조 관점에서 타입을 지정


Structural Typing

구조적 타이핑(Structural Typing)이란 코드 구조 관점에서 각각의 타입 호환 여부를 판단하는 것이다.

interface Person {
  name: string;
}

let person: Person;
// 타입스크립트는 y의 타입을 { name: string; age: number; }로 추론
let mirrer = { name: "Mirrer", age: 10 };
person = mirrer;

위 코드의 Person 인터페이스는 name 속성을 정의했기 때문에 mirrerPerson 타입에 호환될 수 있다.

이는 함수 호출에서도 동일하다.

mirrer 변수에는 name 속성 뿐 아니라 age 속성도 포함되어 있어 아래와 같이 logName 함수의 호출 인자로 전달할 수 있다.

function logName(a: Person) {
  console.log(`저의 이름은 ${a.name}입니다.`);
}
// 위에서 정의한 mirrer 변수, 타입은 { name: string; age: number; }
logName(mirrer);

Soundness

Typescript컴파일 시점 타입을 추론할 수 없는 특정 타입에 대해서 일단 안전하다 판단한다.

이러한 특성은 "들리지 않는다(it is said to not be sound)"라고 표현한다.


Enum Type Compatibility

Enum 타입은 number 타입과 호환되지만, Enum 타입끼리는 호환되지 않습니다.

enum Name { Mirrer, Mirror };
enum City { Seoul, Busan, Jeju };

let name = Name.Mirrer;
status = City.Seoul;  // Error

Class Type Compatibility

Class 타입은 스태틱 멤버(static member)생성자(constructor)제외한 속성만 비교한다.

class Developer {
  name: string;
  constructor(job: string, age: number) { }  
}

class Person {
  name: string;
  constructor(age: number) { }  
}

let dev: Developer;
let person: Person;

dev = person;  // OK
person = dev;  // OK

Generics Type Compatibility

Generic은 타입 간의 호환 여부를 판단 시 타입 인자 <T>의 속성 할당 여부를 기준으로 한다.

아래 코드의 Interface속성(member 변수)이 없어 x, y는 같은 타입으로 간주된다.

interface Empty<T> {

}

let x: Empty<number>;
let y: Empty<string>;

x = y;  // OK, because y matches structure of x

하지만 Interface 속성이 존재하여 Generic 타입 인자가 속성에 할당된다면 서로 다른 타입으로 간주한다.

interface NotEmpty<T> {
  data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;

x = y;  // Error, because x and y are not compatible

참고 자료

TypeScript: JavaScript With Syntax For Types.
React TypeScript Tutorial for Beginners - Codevolution
타입스크립트 입문 - 기초부터 실전까지 - 장기효

profile
memories Of A front-end web developer

0개의 댓글