개발/이펙티브 타입스크립트

[이펙티브 타입스크립트+11] 잉여 속성 체크의 한계 인지하기

Junghyun Kim 2021. 8. 8. 17:53
반응형

2장 타입스크립트의 타입 시스템
아이템 11 | 잉여 속성 체크의 한계 인지하기

3줄 요약
1. 잉여 속성 체크는 타입에 선언된 속성 외에 속성이 있는지 체크한다.
2. 객체 리터럴에서만 잉여 속성 체크가 동작한다. 그래서 엄격한 객체 리터럴 체크라고도 불린다.
3. 일반적인 구조적 할당 가능성 체크와는 역할이 다르다.

참고) 이펙티브 타입스크립트는 타입스크립트의 기본 그 이상을 다룹니다.


잉여 속성 체크는 아래와 같습니다.

jung 변수에 Person 타입을 할당함과 동시에 오브젝트 리터럴 생성.
에러 문구. gender 속성은 Person 타입에 존재하지않는다.

변수에 타입을 선언함과 동시에 오브젝트 리터럴로 만들게 되면 잉여 속성이 체크됩니다.
반면 아래와 같은 경우에는 잉여 속성이 체크되지 않습니다.

hoon 변수에 정상적으로 hyun 변수가 할당되었다.

정상적으로 hoon 변수에 hyun 변수가 할당되었고, 이 과정에서 잉여 속성 체크는 진행되지 않았습니다.
구조적 타이핑이라는 관점에서 봤을 때는 두 번째 예시가 적절해 보이고 첫 번째 예시가 오히려 이상하게 보입니다.

여기서 우리는 할당 가능 검사와 잉여 속성 체크가 별도의 과정이라는 것을 알아야 합니다.

1번 예시와 2번 예시 모두 할당 가능 검사를 통과했습니다.
그러나 잉여 속성 체크는 1번 예시에서만 동작하였고 2번 예시에서는 동작하지 않았습니다.

다른 예 하나를 더 보겠습니다.

hoon은 할당이 되었으나 새로운 객체 리터럴은 에러가 난다.

이미 Person 타입이 된 hoon 변수는 구조적 타이핑 관점에서 함수에 인자로 넘길 수 있습니다.
그러나 새롭게 객체 리터럴로 만든 변수는 잉여 속성 체크에 의해서 에러를 냅니다.

이로 미루어 보아 잉여 속성 체크는 특정 타입에 객체 리터럴을 생성하여 할당할 때 일어나는 것을 알 수 있습니다.
이렇게 객체 리터럴에서 잉여 속성 체크를 하게 될 때에는 장점이 하나가 있습니다.
오타로 인한 의도치 않은 에러를 방지할 수 있습니다.

잉여 속성 체크로 인해 오타를 방지할 수 있다.

'age'라는 속성이 들어와야하지만 'aje'라는 속성이 들어오게 되면서 잉여 속성 체크를 통해 의도치 않은 오타를 방지해줍니다.

이렇게 잉여 속성 체크는 필요한 속성 이외의 속성들을 체크하기 때문에 '엄격한 객체 리터럴 체크'라고도 불립니다.
유용하기는 하지만 타입 단언을 사용할 때에는 잉여 속성 체크를 하지 않습니다.

잉여 속성 체크를 하지 않는다.

또한, 잉여 속성 체크를 우회할 수 있는 방법이 있습니다.
인덱스 시그니처를 사용하면 잉여 속성 체크를 무력화할 수 있습니다.

인덱스 시그니처를 통해 잉여 속성 체크를 무력화.

 

 

Materials From
1. <이펙티브 타입스크립트>(댄 밴더캄 지음, 장원호 옮김, 인사이트 2021)
2. 타입스크립트 공식 홈페이지 | https://www.typescriptlang.org/

 

Typed JavaScript at Any Scale.

TypeScript extends JavaScript by adding types to the language. TypeScript speeds up your development experience by catching errors and providing fixes before you even run your code.

www.typescriptlang.org

 


참고)
선택적 속성만 가지는 약한(weak) 타입에서는 특별하게 '공통 속성 체크'가 동작합니다.
약한 타입은 아래와 같이 생겼습니다.

모든 속성이 Optional인 약한 타입(Weak Type).

그리고 객체 하나를 만들고 해당 객체를 WeakType 객체에 할당해보겠습니다.

soma라는 타입이 WeakType의 속성이 아니라는 에러가 뜬다.

객체 리터럴을 만들 때 타입 선언을 하지 않았기 때문에 잉여 속성 체크가 발생하지 않습니다.
그리고 구조적 타이핑 관점에서 보면 'o' 객체에 'weakObj' 객체에 할당이 되어야 할 것 같지만 에러가 발생합니다.
약한 타입에서만 체크되는 공통 속성 체크 때문입니다.

반응형