본문 바로가기

개발 공부/TS

[우타스 스터디] 2장 타입

타입이란

자료형으로서의 타입

  • 개발자는 타입을 사용해서 값의 종류를 명시할 수 있고 메모리를 더욱 효율적으로 사용할 수 있다.
  • 값의 크기를 명시하면 컴퓨터가 값을 참조할 때 한 번에 읽을 메모리 크기를 알 수 있어 값을 훼손하지 않고 가져올 수 있다.

집합으로서의 타입

  • 컴파일러는 값이 어떤 일을 할 수 있고, 어떤 일을 할 수 없는지 사전에 알 수 있다.
  • 유효한 값의 범위를 제한해서 런타임에서 발생할 수 있는 유효하지 않는 값에 대한 에러를 방지한다.

정적타입과 동적 타입

  정적 타입 동적 타입
실행 시점 컴파일 타임 런타임
개발자 타입 명시 O X
에러 발견 시점 컴파일 타임 타입 에러 발견 프로그램 실행 시 타입 에러 발견
이점 안정성 보장 개발 과정에서 에러 발생 없음
더보기

- 컴파일타임이란? 기계(컴퓨터, 엔진)가 소스코드를 이해할 수 있도록 기계어로 변환되는 시점

- 런타임이란? 변환된 파일이 메모리에 적재되어 실행되는 시점

강타입과 약타입

  • 강타입이란?
    • 서로 다른 타입을 갖는 값끼리 연산을 시도하면 컴파일러 또는 인터프리터에서 에러가 발생한다.
  • 약타입이란?
    • 서로 다른 타입을 갖는 값끼리 연산할 때는 컴파일러 또는 인터프리터가 내부적으로 판단해서 특정 값의 타입을 변환하여 연산을 수행한 후 값을 도출한다.
  • 자바스크립트는 약타입 언어작성자의 의도와 다르게 동작할 수 있기 때문에 예기치 못한 오류가 발생할 가능성이 높다
  • 즉, 타입을 사용하면 프로그램이 유효하지 않은 작업을 수행하지 않도록 방지할 수 있다.

컴파일 방식

  • 타입스크립트를 컴파일하면 타입이 모두 제거된 자바스크립트 소스코드만이 남게 된다.
  • 자바스크립트에 타입이라는 레이어를 끼얹은 일종의 템플릿 언어 또는 확장 언어로 해석할 수 있다.

타입스크립트의 타입 시스템

타입 애너테이션 방식

  • 타입 애너테이션이란?
    • 타입을 명시적으로 선언해서 어떤 타입 값이 저장될 것인지를 컴파일러에 직접 알려주는 문법이다.
  • 사용법
    • 변수 이름 뒤에 : type 구문을 붙여 데이터 타입을 명시한다
let isActive:boolean =  false;

구조적 타이핑

타입스크립트는 구조로 타입을 구분한다(구조적 타이핑)

더보기

타입을 사용하는 다른 프로그래밍 언어는 명목적으로 구체화한 타입시스템 방식을 사용하고 있다.

 

명목적으로 구체화한 타입시스템이란?

- 값이나 객체는 하나의 구체적인 타입을 가지고 있다.

- 타입은 이름으로 구분되며, 컴파일 타입 이후에도 남아있다.

- 명확한 상속 관계나 공통으로 가지고 있는 인터페이스가 없다면 타입은 서로 호환되지 않는다.

구조적 서브타이핑

구조적 타이핑이란?

  • 객체나 데이터의 구조에 기반하여 타입 호환성을 결정하는 타입 시스템(타입 내부 구조에 의해 결정)
  • 즉, 객체가 특정한 타입으로 정확히 명시되어 있지 않아도, 객체의 구조가 타입과 일치하는지를 확인하여 타입 호환성을 결정한다.
  • 타입이 계층 구조로부터 자유롭다
  • 아래 homeCafe는 menu를 가지고 있기 때문에 호환이 가능하다
type Cafe = {
    menu: string;
}

type Home = {
    todo: string;
}

// 특정 타입으로 정확히 명시되어있지 않더라도
const homeCafe = {
    menu: "cake",
    todo: "sleeping",
}

// 객체의 구조가 일치하는지 '타입 호환성' 확인
const ediya: Cafe = homeCafe;

 

구조적 서브 타이핑이란?

  • 집합으로 나타낼 수 있는 타입스크립트의 타입 시스템을 지탱하고 있는 개념
type stringOrNumber = string | number;
  • 이름이 다른 객체라도 가진 속성이 동일하다면 서로 호환이 가능한 동일한 타입으로 여긴다.

자바스크립트를 닮은 타입스크립트

명목적 타이핑이란?

  • 타입의 구조가 아닌 타입의 이름만을 가지고 구별
  • 변수에 타입을 명시하는 과정에서 에러를 내뱉기 때문에 구조적 타이핑에 비해 안전하다
  • 객체의 속성을 다른 객체의 속성과 호환도지 않도록 하여 안전성을 추구한다
  • 예시: C++,  자바

타입스크립트는 왜 구조적 타이핑을 채택했을까?

자바스크립트(덕 타이핑 기반)를 모델링한 언어이기 때문이다.

즉, 자바스크립트의 특징을 받아들여 객체나 함수가 가진 구조적 특징을 기반으로 타이핑하는 방식을 택했다.

더보기

덕 타이핑이란?

어떤 함수의 매개변숫값이 올바르게 주어진다면 그 값이 어떻게 만들어졌는지 신경 쓰지 않고 사용한다는 개념이다.

즉, 어떤 타입에 부합하는 변수와 메서드를 가질 경우 해당 타입에 속하는 것으로 간주하는 방식

예: 어떤 새가 오리처럼 걷고, 헤엄치며 꽥꽥 거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다

  덕 타이핑 구조적 타이핑
타입 검사 시점 런 타임 컴파일 타임
공통점 모두 객체 변수, 메서드 같은 필드를 기반으로 타입을 검사
사용하는 곳 동적 타이핑 정적 타이핑

구조적 타이핑의 결과

->스터디에서 토론하고 넣을 예정임

타입스크립트의 점진적 타입 확인

타입스크립트는 점진적으로 타입을 확인하는 언어이다.

  • 점진적 타입 검사란?
    • 컴파일 타임에 타입을 검사하면서 필요에 따라 타입 선언 생략을 허용하는 방식
function add(x,y){return x+y};

function add(x:any,y:any):any;
  • 위 코드를 통해서 add() 함수의 인자 x,y와 함수의 반환 값을 보두 any 타입으로 추론한다.
  • 죽, 필요에 따라 타입을 생략할 수도 있고 타입을 점진적으로 추가할 수도 있다
  • 이러한 특징으로 정적타입의 정확성을 100% 보장해주지 않는다. 모든 타입을 컴파일 타임에 검사하지 않아도 되기 때문에 타입이 올바르게 정해지지 않으면 런타입에서 에러가 발생하기도 한다.
더보기

any 타입이란?

모든 타입 종류를 포함하는 가장 상위 타입으로 어떤 타입 값이든 할당 할 수 있다.

단, 타입스크립트의 컴파일 옵션인 noImplicitAny 값이 true일 때 에러가 발생한다. 하지만 정확한 타이핑을 위해 tsconfig에서 옵션을 true로 설정해주는 게 좋다.

자바스크립트 슈퍼셋으로서의 타입스크립트

타입스크립트는 기존 자바스크립트 코드에 정적인 타이핑을 추가한 것으로 자바스크립트의 상위 집합이다.

값 VS 타입

  • 값은 프로그램이 처리하기 위해 메모리에 저장하는 모든 데이터다. 문자열, 숫자, 변수, 매개변수, 객체, 함수(자바스크립트만) 등이 해당한다. 함수는 런타임에서 객체로 변환된다.
  • type으로 선언한 내용은 자바스크립트 런타임에서 제거되기 때문에 값 공간과 타입 공간은 서로 충돌하지 않는다
  • 타입은 주로 타인 선언 또는 단언문(as)으로 작성하고 값은 할당 연산자인 =으로 작성한다.
  • 타입스크립트는 값과 타입을 함계 사용하는데, 별도의 네임스페이스에 존재한다.
    • 값이 사용되는 위치와 타입이 사용되는 위치가 다르기 때문에, 코드가 어디에서 사용되었는지에 따라 타입인지 값인지를 추론할 수 있다.
    • 값-타입 공간을 홍돈하는 문제를 해결하기 위해 값고 타입을 구분해서 작성해야한다
interface Writer{
name:string;
isWriter:boolean;
}

function Comment({author, date}:{author:Writer, date:Date}){...}

값과 타입 공간에 동시에 존재하는 심볼

클래스

  • 타입스크립트 코드에서 클래스는 값과 타입 공간 모두 포함될 수 있다.
  • 런 타입에서 객체로 변환 되어 자바스크립트의 값으로 사용된다.
class Developer {
  name: string;
  domain: string;

  constructor(name: string, domain: string) {
    this.name = name;
    this.domain = domain;
  }
}
//me: 뒤에 Developer는 타입에 해당, new 뒤에 Developer는 클래스의 생성자 함수인 값으로 동작
const me: Developer = new Developer('zig', 'frontend');

enum

타입 공간에서 타입을 제한하는 역할을 하지만, 자바스크립트 런타임에서 실제값으로도 사용될 수 있다.

//타입 제한
enum WeekDays {
  MON = 'Mon',
  TUES = 'Tues',
  WEDNES = 'Wednes',
  THURS = 'Thurs',
  FRI = 'Fri',
}

type WeekDaysKey = keyof typeof WeekDays;
function printDay(key: WeekDaysKey, message: string) {
  const day = WeekDays[key];
  ...
}

//값 공간
enum WeekDays {
  MON = 'Mon',
  TUES = 'Tues',
  WEDNES = 'Wednes',
  THURS = 'Thurs',
  FRI = 'Fri',
}

function printDay(palette: { MON: string }) {
  return palette.MON;
}

printDay(WeekDays);
키워드 타입
class Y Y
const, let, var Y N
enum Y Y
function Y N
interface N Y
type N Y
namespace Y N

enum을 어떻게 사용할까?

  1. 유니온 타입은 타입이어서 순회 불가, enum은 값이기 때문에 이터러블하다. 즉, enum은 값이기 때문에 검증이 가능하다.
  2. enum은 트리쉐이킹이 되지 않아 번들 사이즈에 영향을 줄 수 있지만, const enum을 사용하면 해결할 수 있다.
  3. enum이 들어갈 수 있는 값을 타입으로 강제해놓고 객체로 만들어야 맞지 않나 생각이 많이 든다. enum의 리버스 매핑 기능은 컴파일러에서 처리 되면 안되는 동작이다.
  4. enum을 사용하면 자바스크립트 컴파일 될 때 IIFE로 바뀌는 게 크진 않지만 성능에 영향을 줄 수 있다.

enum 외에 const enum을 왜 사용하는지?

장점: 외부에서 전역적으로 참조할 때는 const enum을 사용한다. const enum은 빌드 과정에서 참조 값만 남기기 때문에 트리쉐이킹이 된다는 장점이 있다.

단점: enum과 다르게 직접적인 값으로 치환되기 때문에 전체 네임스페이스에 접근하지 못하고 순회할 수도 없다는 단점을 가지고 있다.

더보기

트리쉐이킹이란?

자바스크립트와 타입스크립트에서 사용하지 않는 코드를 삭제하는 방식이다. 

ES6 이후 웹팩, 롤업 같은 모듈 번들러를 사용하는데, 이 도구를 사용하여 번들링 작업을 수행 시 사용하지 않는 코드는 자동으로 삭제된다.

 

이터러블이란?

반복 가능한 것을 의미한다.

 

번들사이즈란?

만든 서비스가 더욱 빠르고, 원활하게 사용자가 사용할 수 있게 하기 위한 지표 중 하나로 자바스크립 코드의 크기를 뜻한다.

즉, 코드의 크기(용량)가 작을 수록 사용자가 다운로드받아야 할 용량이 줄어들어 빠르게 실행될 수 있다.

 

enum의 리버스 매핑 기능이란?

숫자형 enum에만 존재하는 특징이다. enum의 key로 value를 얻을 수 있고, value로 key를 얻을 수 있다.

enum Enum {
  A
}
let a = Enum.A; // 키로 값을 획득 하기
let keyName = Enum[a]; // 값으로 키를 획득 하기

타입을 확인하는 방법

typeof

연산하기 전에 피연산자의 테이터타입을 나타내는 문자열 반환하며 값에서 쓰일 때와 타입에서 쓰일 때의 역할이 다르다.

(boolean,null, undefined,Number,BigInt,String,Symbol,Function, 호스트 객체, object)

값에서 쓰일 때

자바스크립트 런타임의 typeof 연산자가 된다.

 

타입으로 쓰일 때

타입스크립트의 타입을 반환한다.

 

interface Person {
  first: string;
  last: string;
}

const person: Person = { first: 'zig', last: 'song' };

function email(options: { person: Person; subject: string; body: string }) {}

//값에서 사용되는 typeof
const v1 = typeof person; //object
const v2 = typeof email; //function
//타입으로 사용되는 typeof
type T1 = typeof person; //person
type T2 = typeof email; //(options:{person: Person; subject: string; body: string}) => void;

타입 단언

as 키워드를 사용하여 타입을 강제할 수 있다.

강제 형 변환과 유사한 기능을 제공한다.

더보기

타입 스크립트 코드 -> 자바스크립트 변환

타입스크립트의 타입시스템 및 문법-> 컴파일 단계에서 제거

컴파일 단계에서 타입 단언 형 변환 강제-> 런타임 효력 발휘 X

원시 타입

boolean, undefined, null, number, bigInt, string, symbol

더보기

원시 래퍼 객체란?

타입을 파스칼 표기법으로 표기하면 자바스크립트에서 부르는 객체이며 null과 undefined를 제외한 모든 원시 값은 해당 원시 값을 래핑한 객체를 가진다.

boolean

자바스크립트에는 형 변환을 통해 true/false로 취급되는 Truthy/Falsy 값이 존재한다.

Truthy/Falsy 값은 boolean 타입에 해다하지 않는다.

undefined와 null

undefined는 원래부터 없는 값

null은 의도적으로 명시적으로 할당한 값

객체 타입

원시 타입에 속하지 않는 값

object

가급적 사용하지 말도록 권장하는데 객체에 해당하는 모든 타입 값을 유동적으로 할당할 수 있어 정적 타이핑의 의미가 크게 퇴색된다.

{}

지정된 객체에는 어떤 값도 속정으로 할당할 수 없다.

객체 래퍼에서 제공하는 속성에는 정상적으로 접근할 수 있다.

array

타입스크립트에서 하나의 타입 값만 가질 수 있다.

튜플의 대괄호 내부에는 선언 시점에 지정해준 타입 값만 할당할 수 있다.

const targetCodes: ['CATEGORY', 'EXHIBITION'] = [
  'CATEGORY',
  'EXHIBITION',
  'S',
];//S는 지정할 수 없다

type과 interface 키워드

반복적으로 사용돼도 중복 없이 해당 타입을 쓸 수 있다.

타입스크리븥에서는 일반적으로 변수 타입을 명시적으로 선언하지 않아도 컴파일러가 자동으로 타입을 추론한다.

즉, 컴파일러가 변수 사용 방식과 할당된 값의 타입을 분석해서 타입을 유추한다는 것을 의미한다.

function

//a,b는 값 타입이고, 괄호 옆 :number는 rturn되는 값의 타입이다
function add(a: number, b: number): number {
  return a + b;
}

 

본 글은 우아한 타입스크립트 With 리액트를 보며 스터디한 내용을 요약 정리한 글입니다.

참고

 

[TypeScript] 구조적 타이핑으로 타입 호환성 확인하기, 덕 타이핑이란?

[TypeScript] 구조적 타이핑으로 타입 호환성 확인하기, 덕 타이핑이란? 📌 구조적 타이핑의 정의 구조적 타이핑은 객체나 데이터의 구조에 기반하여 타입 호환성을 결정하는 타입 시스템 구조적

ramincoding.tistory.com

 

Home

Personal blog by kimcoder

www.kimcoder.io

 

 

Next.js CI 단계에서 번들 사이즈 확인하기 - hyesungoh

Github actions를 이용해 PR 코멘트와 이슈에서 route 별 번들 사이즈를 확인하는 법을 공유합니다.

www.hyesungoh.xyz

 

 

우아한 타입스크립트 with 리액트 | 우아한형제들 - 교보문고

우아한 타입스크립트 with 리액트 | 주니어 프론트엔드 개발자를 위한 타입스크립트+리액트 온보딩 가이드 우아한형제들은 자바스크립트와 자체 개발 웹 프레임워크인 WoowahanJS를 사용했었다. 그

product.kyobobook.co.kr