Home Effective Typescript 스터디 2주차 (Item 6 ~ 10)
Post
Cancel

Effective Typescript 스터디 2주차 (Item 6 ~ 10)

DesktopView

이 게시물은 SW 마에스트로 연수생 간 진행한 Effective Typescript 스터디의 개인 정리 내용입니다

[ Item 06 ] 편집기를 이용하여 타입시스템 탐색하기


편집기를 이용하여 타입시스템 탐색하기

항상 ts컴파일러의 존재만 인식하고 사용했는데,

일반적으로 마우스를 올릴 때 Type 가이드 같은 기능들이 전부 tsServer의 기능들이었습니다.

매 타이핑마다 vsCode는 tsServer 에 요청을 보내고 코드 완성, 코드 탐색, 심볼 등과 같은 기능들을 응답받게 됩니다.

⇒ 이를 통해 우리가 Type 가이드와 같은 실시간 피드백을 받아볼 수 있었던 것입니다.

결론

단순히 ts를 사용했으니 더욱 짜임새 있는 코드가 되었다고 머무르는 것이 아니라, tsServer가 제공해주는 실시간 피드백과 같은 기능들을 통해 함수, 메서드, 객체 그리고 조건문 내부에서 이루어지는 타입추론들을 들여다 보고 타입추론의 흐름을 이해해보기를 제안하는 듯 합니다.

[ Item 07 ] 타입이 값들의 집합이라고 생각하라.


타입이 값들의 집합이라고 생각하라.

듣고있던 인프런 강의에서도 타입시스템을 이해하는데 추천하는 방법이었습니다.

사실 코드에서 타입을 선언하며 이것이 어떤 집합 다이어그램을 그릴 것이며, 유니언 타입을 사용할 때의 집합 다이어그램을 연상하는것은 쉽진 않을 것입니다.

하지만 타입시스템을 조금 더 깊이 이해하기엔 충분히 좋은 방법인것은 동의합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interface Korean {
	firstName:string;
	lastName:string;
	age:number; 
}

interface CSKIM {
	firstName:string;
	lastName:string;
	age:number; 
	favorite:string // 좋아하는 것
}

type Charles = Korean & CSKIM

const CSKIM_Charles : Charles = {
	firstName:"Chansub";
	lastName:"Kim";
	age:29; //😥 
	favorite:"coffee";
}

책에서도 나오는 교집합 관련 예제입니다.

우리가 직관적으로 생각하기에 집합으로 생각하더라도 Korean 의 요소들과 CSKIM 의 요소 중 겹치는 부분인 firstName,lastName,age 가 나와야 하는 것 아닐까요?

라고 생각할 수 있지만 이것을 다이어그램으로 구성해서 생각 해 본다면 위와 같은 반환을 이해할 수 있다.

1
2
3
4
5
6
7
8
interface animal {
	leg : string;
}

interface bird {
	leg : string;
	wing : string;
}

과거 EC씨가 이 코드와 유사한 구조에서 왜 animal이 bird 보다 더 큰 개념인지 이해하기 어렵다~~ 라는식으로 얘기를 했던 것이 기억이 납니다.

이 또한 집합을 대입한다면 어렵지 않게 이해할 수 있습니다.

1
type test = string & number // never

그에 더해서 이 부분도 이해할 수 있게 되구요.

[ Item 08 ] 타입 공간과 값 공간의 심벌을 구분하라.


타입 공간과 값 공간의 심벌을 구분하라.

흔히 사용하는 instanceof 연산자 때문에 헷갈릴 수 있는 부분이 있습니다.

1
2
3
4
5
function test(a:Date) :void{
	if ( a instanceof Date ) {
		console.log(' a is Date ')
}
}

라는 코드가 있을 때 콘솔에는 a is Date 라는 메세지가 찍힙니다. 왜 일까요??

여기서 Date 는 원시타입? 이지만 동시에 JS 에 내장되어있는 클래스이기 때문입니다.

instanceof 연산자는 ‘왼쪽 값이 오른쪽 “클래스” 의 인스턴스인가?’ 에 대한 답을 내놓습니다.

따라서 이러한 과정을 거쳐서 49 페이지의 실린더 클래스 예제또한 내부에서 ‘타입’이 실린더로 나오는 이유도 이러한 눈속임을 통해 타입스크립트가 속게 되고, 속은 타입스크립트는 어쨌든 내부 shape 는 Cylinder 라는 타입 이라는 추론을 내놓게 되는 것이죠.

결론

Item 08에서의 골자는 타입과 값(객체) 들의 이름이 겹칠 수 있다는 휴먼에러를 줄이라는 뜻 같습니다.

타입 구역과 값 구역이 다르기때문에 이름이 겹칠 수 있고, 이것을 ts는 구분할 수 없기 때문에 어쩌면 JS 의 빈틈이라고 할 수 있는 클래스와 같은 문제로 나중에 타입과 값 이름을 같게해서 의도치 않은 에러를 만들지 말아라! 또한 이러한 꽤 크리티컬한 엣지케이스를 통해 TS 를 더욱 깊게 이해할 수 있으면 좋겠다 라는 뜻으로 보입니다.

[ Item 09 ] 타입 단언보다는 타입 선언을 사용하라.


타입 단언보다는 타입 선언을 사용하라.

타입 단언은 ‘어.쨌.든 이건, 이 타입이니 오류를 무시해라’ 라는 의미로 사용될 수 있습니다.

이것은 가장 지양해야 할 ANY 남발과 같은 의미로 받아들일 수 있습니다.

물론 ANY 보다는 나은 방법이겠지만, 이러한 리스크를 지면서 안정성체크까지 해주는 타입선언을 굳이굳이 무시하고 비교적 비효율적인 타입단언을 사용 할 이유를 저는 아직까지는 잘 모르습니다.

하지만 타입스크립트도 앞선 Item 8 과 같이 언제나 완벽할 순 없습니다.

타입스크립트보다도 프로그래머 자신이 더욱 해당 타입에 대해서 명확히 알고 있다면 타입단언을 사용해도 무방한 듯 합니다.
( 단, 명시한대로 명.확.히 알고있을 때 ! )

[Item 10 ] 객체 래퍼 타입 피하기


객체 래퍼 타입 피하기

JS 에서 기본형인 string 에는 메서드가 없지만, 객체 타입인 String 에는 메서드들이 존재합니다. 여기서 JS 의 느슨함이 string 과 String 을 유연하게 변환하며 사용하게 됩니다.

사실 여기서 피하라고 하는 객체타입은 많은 부분에서 그대로 객체타입을 사용하더라도 문제를 발견하지 못할 가능성이 큽니다.

앞서 말한대로 JS 에서 기본형과 객체타입은 유연하게 변환되기때문에, 만약 기본형으로 선언 후 속성을 할당한다면, 객체로 변환 후 속성이 할당되고 다시 기본형으로 돌아가야 하기 때문에 속성이 할당 된 객체가 버려져 우리가 예상한 것과는 다른 반환값을 만나볼 수 있게 됩니다.

This post is licensed under CC BY 4.0 by the author.