Structural Type System

nearworld·2023년 1월 24일
0

typescript

목록 보기
18/28

들어가기에 앞서 용어 정리

구조적 타이핑 Structural Type System
타입 A 와 B가 있다고 가정하고 A 와 B를 비교할 때 A와 B가 서로 관련이 없는 독립적 타입이더라도 타입 내부의 구조에 같은 부분이 있다면 같은 타입으로 보는 타입 시스템
타입스크립트가 구조적 타입 시스템을 사용한다.

명시적 타이핑 Nominal Type System
타입 A와 B가 있다고 가정하고 A 와 B를 비교할 때 A와 B가 서로 상속관계인 경우에 같은 타입으로 보는 타입 시스템이며 관련이 없는 독립적 타입들은 그냥 말그대로 다른 타입으로 인식하는 타입 시스템. JAVA가 명시적 타입 시스템을 사용한다.

코드로 구조적 타이핑, 명시적 타이핑 알아보기

type Person = {
  name: string;
}
type AgedPerson = {
  name: string;
}

PersonAgedPerson 타입은 서로 상속관계가 아닌 독립적인 타입들이다.
명시적 타입 시스템을 사용하는 언어의 경우 두 타입은 독립적이므로 서로 다른 타입으로 인식된다.
구조적 타입 시스템을 사용하는 언어의 경우 두 타입이 독립적이더라도 내부 구조인 프로퍼티가 같은 게 있으므로 같은 타입으로 인식된다.

type Person = {
  name: string;
}
type AgedPerson = {
  name: string;
}
// `name` 프로퍼티를 가지고 있는 객체 리터럴을 `Person` 타입의 변수에 할당.
const person: Person = { name: 'kim' };

위 코드는 정상적으로 작동한다. 하지만 아래의 코드를 보면 헷갈릴 수 있다.

type Person = {
  name: string;
}
type AgedPerson = {
  name: string;
}
const aged = { name: 'kim', age: 100 };
const person: Person = aged; // Person 타입은 age 프로퍼티가 없음에도 할당 가능


aged 변수에 값으로 할당된 객체의 프로퍼티중 age가 있음에도 불구하고 자동 코드 완성 목록에는 name 프로퍼티만 나타나는 것을 알 수 있다.

타입은 해당 타입에 들어맞는 값들의 집합으로 볼 수 있는데 Person 타입의 집합은 name 프로퍼티를 가지고 있는 모든 값 즉 조건을 충족하는 모든 객체들의 집합이다.
그렇기에 aged변수에 할당된 객체가 age 프로퍼티를 가지고 있더라도 name 프로퍼티를 갖고 있는 객체가 되므로 Person 타입의 집합에 속한다.

type Person = {
  name: string
}
type AgedPerson = {
  name: string;
  age: number;
}

const person: Person = {
  name: 'kim',
  age: 100
};

이제 위 코드를 보면 Person 집합에 age 프로퍼티가 있기 때문에 코드가 정상적으로 작동한다고 생각할 수 있다. 하지만 에러가 발생한다.

Type '{ name: string; age: number; }' is not assignable to type 'Person'.
  Object literal may only specify known properties, and 'age' does not exist in type 'Person'.(2322)

타입스크립트에서 객체를 변수에 할당 시에는 특수 케이스 취급을 받는다고 공식 문서에 나와있다.

특수 케이스 취급 을 받게 되는 경우는 초과 프로퍼티 체크가 발생하며
아래의 2가지 상황일 때 초과 프로퍼티 체크가 발생된다.

  • 객체 리터럴을 함수의 인자로 패스할때
  • 객체 리터럴을 변수에 할당할때

초과 프로퍼티 체크 기능은 개발자가 초기에 타입이 명시된 변수에 값을 할당할때 잘못된 값을 할당하는 것을 방지해준다.

객체 리터럴 초과 프로퍼티 체크 관련 공식문서 링크 https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks

profile
깃허브: https://github.com/nearworld

0개의 댓글