이 영역을 누르면 첫 페이지로 이동
Nuhends 의 Tech Life 블로그의 첫 페이지로 이동

Nuhends 의 Tech Life

페이지 맨 위로 올라가기

Nuhends 의 Tech Life

IT / Tech / 재테크 관련 뉴스를 최대한 알기 쉽게 전달하는 Tech 블로그 입니다.

[이펙티브 타입스크립트] 타입 공간과 값 공간의 심벌 구분하기

  • 2022.06.05 20:00
  • 프로그래밍/Typescript
반응형

 

타입스크립트의 심벌(symbol)은 타입 공간이나 값 공간 중의 한 곳에 존재한다.

심벌은 이름이 같더라도 속하는 공간(타입 or 값)에 따라 다른 것을 나타낼 수 있기 때문

// Cylinder은 타입으로 사용
interface Cylinder {
	radius: number;
	height: number;
}

// Cylinder로 이름은 같지만 값으로 사용
const Cylinder = () => (radius: number, height: number) => ({ radius, height });

// => Cylinder는 상황에 따라 타입 or 값으로 둘다 사용될 수 있음

function calcVolume(shape: unknown) {
	if(shape instanceof Cylinder) {
		console.log(shape.radius); // 오류
	}
}

instanceof를 이용하여 shape가 Cylinder 타입인지 체크해보자는 의도였지만 중요한 점은 instanceof는 자바스크립트의 런타임 연산자 → 값에 대한 연산을 수행하기 때문에 Cylinder 함수를 참조하게 된다.

 

그렇다면 타입과 값은 어떻게 구분할 수 있는가? 이는 조금 혼란스러울 때가 많다.

type T1 = 'string literal';
type T2 = 123;

const V1 = 'string literal';
const V2 = 123;
  • 일반적으로 type, interface 다음에 오는 심벌은 타입
  • const, let 선언에 쓰이는 건 값

 

typescirpt 플레이그라운드를 활용하기

  • ts 소스로부터 변환된 js 결과물을 보여줌
  • 컴파일 과정에서 타입 정보는 제거되기 때문에, 심볼이 사라졌다면 그것은 타입에 해당

 

타입과 값 구별해보기

  • 앞선 규칙에 추가
  • 타입 선언 :, as 다음에 오는 심벌은 타입
  • = 다음에 오는 값은 무조건 값
interface Person {
	first: string;
	last: string;
}

const p: Person = { first: 'Jane', last: 'Jacobs' };

function email(p: Person, subject: string, body: string): Response { 
	// ... 
}

 

상황에 따라 type과 값 모두 가능한 예약어 class

class Cylinder {
	radius=1;
	height=1;
}

function calcVolume(shape: unknown) {
	if(shape instanceof Cylinder) {
		console.log(shape);
		console.log(shape.radius);
	}
}

Cylinder 클래스는 타입으로 사용 (값으로 쓰일 때는 생성자가 사용되는 경우)

 

타입과 값에서 다른 기능을 하는 typeof 연산자

type T1 = typeof p;      // Person 타입이라고 가정
// type은 (p: Person, subject: string, body: string) => Response
type T2 = typeof email;   

const v1 = typeof p;     // 값은 "object"
const v2 = typeof email;  // 값은 "function" 

타입의 관점

  • typeof는 값을 읽고 ts 타입을 리턴
  • 타입 공간의 typeof는 큰 타입의 일부분으로 사용
  • type 구문으로 type에 이름을 붙이는 용도로도 사용

값의 관점

  • js 런타임의 typeof 연산자
  • 값 공간의 typeof는 문자열을 반환

js 런타임의 타입은 ts의 정적 타입 시스템보다 훨씬 간단하다.

  • js 런타임의 타입: number / boolean / undefined / object / function

 

클래스에 대한 typeof는 상황에 따라 다르게 동작한다.

const v = typeof Cylinder;  // 값이 "function"
type T = typeof Cylinder;   // ??

declare let fn: T;
const c = new fn(); // 타입이 Cylinder

// InstanceType 제너릭을 사용해 생정자 타입과 인스턴스 타입을 전환할 수 있음
type C = InstanceType<typeof Cylinder>;

declare let smallC: C;
  • 클래스가 js런타임에서 실제 함수로 구현되기 때문에 v는 “function”
  • 중요한 점은 Cylinder은 인스턴스 타입이 아니라는 점, (=생성자 함수)

 

속성선택자 [ ]

const first: Person['first'] = p['first'];

// 인덱스 위치에는 유니온 타입과 기본형 타입을 포함한 어떤 타입이든 사용 가능
type PersonEl = Person['first' | 'last'];  // string
type Tuple = [string, number, Date];
type TupleEl = Tuple[number];    // string | number | Date

속성선택자 []는 타입으로 쓰일 때에도 값에서 사용하는 것과 동일하게 동작

하지만 obj[’filed’]와 obj.filed는값이 동일하더라도 타입은 다를 수 있음 (?) → 타입의 속성을 얻을 때에는 반드시 obj[’filed’]를 사용해야 한다 (속성 선택자에 대한 내용은 아이템 14에서 더 자세히 다룰 예정)

 

두 공간(타입, 값)사이에서 다른 의미를 가지는 코드 패턴들

  • this 키워드 (아이템 49)
    • 값으로 쓰이는 this: 자바스크립트의 this 키워드
    • 타입으로 쓰이는 this: 다형성(polymorphic) this 라고 불리는 this → 서브클래스의 메서드 체인 구현할 때 유용
  • &와 |
    • 값: AND 와 OR 비트 연산자
    • 타입: 인터섹션과 유니온
  • const
    • 값: 새 변수 선언
    • 타입: as const는 리터럴 혹은 리터럴 표현식의 추론된 타입을 변경(아이템 21)
  • extends
    • 서브 클래스(class A exnteds B)
    • 서브 타입(interface A extends B)
    • 제너릭 타입의 한정자(Generic<T extends number>)
  • in
    • 루프(for (key in object)) 또는 매핑된(mapped) 타입
function email(options: { person: Person, subject: string, body: string }) {
	// ...
}

function email({ 
    person: Person, 
    subject: string, 
    body: string, 
}) { 
	// ...
}
  • 'Person' is declared but its value is never read.ts(6133)
  • Duplicate identifier 'string'.(2300) Binding element 'string' implicitly has an 'any' type.(7031)

→ 값의 관점에서 Person과 string이 해석되었기 때문에 오류 발생

// 타입과 값을 구분해야 한다.
function email({ 
	person, subject, body 
}): { persone: Person, subject: string, body: string } { 
	// ...
}

 

요약

  • ts 코드를 읽을 때 타입인지 값인지 구분하는 방법을 터특하자 (타입스크립트 플레이그라운드 활용하여 개념잡자)
  • 모든 값은 타입을 가지지만, 타입은 값을 가지지 않는다. type과 interface 같은 키워드는 타입 공간에만 존재
  • class나 enum 같은 키워드는 타입과 값 두가지로 사용될 수 있다.
  • “foo”는 문자열 리터럴이거나, 문자열 리터럴 타입일 수 있다. 차이점을 알고 구별하는 방법을 터득하자.
  • typeof, this 그리고 많은 다른 연산자들과 키워드들은 타입 공간과 값 공간에서 다른 목적으로 사용될 수 있다.
반응형
저작자표시 비영리 변경금지 (새창열림)

'프로그래밍 > Typescript' 카테고리의 다른 글

[이펙티브 타입스크립트] 객체 래퍼 타입 피하기  (0) 2022.06.10
[이펙티브 타입스크립트] #4 구조적 타이핑에 익숙해지기  (0) 2022.06.05
[TypeScript] e.target.target 타입 에러가 나는 이유 ts(2339)  (0) 2022.06.04

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [이펙티브 타입스크립트] 객체 래퍼 타입 피하기

    [이펙티브 타입스크립트] 객체 래퍼 타입 피하기

    2022.06.10
  • [이펙티브 타입스크립트] #4 구조적 타이핑에 익숙해지기

    [이펙티브 타입스크립트] #4 구조적 타이핑에 익숙해지기

    2022.06.05
  • [TypeScript] e.target.target 타입 에러가 나는 이유 ts(2339)

    [TypeScript] e.target.target 타입 에러가 나는 이유 ts(2339)

    2022.06.04
다른 글 더 둘러보기

정보

Nuhends 의 Tech Life 블로그의 첫 페이지로 이동

Nuhends 의 Tech Life

  • Nuhends 의 Tech Life의 첫 페이지로 이동
반응형

검색

메뉴

  • 홈
  • 웹 개발
  • 경제 데이터
  • 경제 공부
  • 방명록

카테고리

  • 분류 전체보기 (127)
    • 프로그래밍 (69)
      • React (3)
      • HTML&CSS 사전 (13)
      • JAVASCRIPT 사전 (11)
      • Algorithm (23)
      • 이슈 정리 (2)
      • 개발 환경 (4)
      • NodeJS (1)
      • Typescript (4)
      • NextJS (5)
      • React-Query (2)
      • ai (1)
    • 경제 데이터 (22)
      • 주식 순위 (20)
      • 경제지표 (2)
    • 경제 공부 (25)
      • 경제 신문 읽기 (3)
      • 세금 재테크 (7)
      • 인사이트 (4)
      • 경제용어정리 (9)
      • 정부 지원 제도 관련 (2)
    • 팁 모음 (11)
      • 인터넷 (5)
      • 생활 (3)
      • SNS 맛집 (3)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 프로그래머스
  • 코테
  • 코테 풀이
  • softeer
  • 자바스크립트
  • 코딩테스트
  • 알고리즘
  • javascript

나의 외부 링크

정보

nuhends의 Nuhends 의 Tech Life

Nuhends 의 Tech Life

nuhends

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © nuhends. Designed by Fraccino.

티스토리툴바