[Typescript] Interface 와 type (feat. utility type)

Falcon·2021년 6월 25일
1

javascript

목록 보기
6/28
post-thumbnail

🎯 Goal

  • d.ts 파일을 생성하여 타입을 선언할 수 있다.
  • interface 키워드를 사용하여 타입을 정의 할 수 있다.
  • type 키워드를 사용하여 타입을 정의 할 수 있다.
  • type 과 interface 의 차이점을 이해할 수 있다.

Sub Goal

Utility Type 을 통해 Custom Type을 유연하게 활용한다.

  • Pick
  • Partitial
  • Required

When to use *.d.ts ?

  • Library 를 만들 때
  • OOP 를 도입하여 생산성을 향상시키고자 할 때
  • 복잡한 데이터 구조 객체를 정의할 때

Interface?

An interface defines the specifications of an entity. what needs to be done but doesn’t specify how it will be done.

다음 요소를 포함한다.

  • name of all properties with type
  • the signature for functions and return type

type vs interface


type keys = 'actionType' | 'userId' | 'uuid' | 'fingerPrint';

// computed value 
export type conditionParameters = {
    [key in keys] : string[] | undefined
}


// interface 는 computed value 사용 불가능
export interface OptionalParameters {
    // readonly keyword 사용 가능
    // ? 로 nullable 컨트롤 가능.
    actionType : string[] | string | undefined,
    userId : string | undefined,
    uuid : string[] | string|  undefined,
    fingerPrint : string[] | string | undefined
}

When to use?

interfaces help in defining a concrete plan for the implementation of an entity


Utility Type

공통의 type, interface 를 다양하게 조정하여 쓸 수 있도록 하는 타입 조정 키워드이다. 여기서는 Pick, Partial, Required 만 알아보자.

Pick

일부 Property 만 타입으로 사용할 때

export interface News {
    readonly pressName: string;
    readonly publishingDate: Date;
    updateDate?: Date;
}

export interface MainNews extends News {
    warning: boolean;
}

// 2개의 속성(pressName, warning) 만 받아서 씀
const nullableMainNews: Pick<MainNews, 'pressName' | 'warning'> = {pressName: 'mail economy', warning : false}
console.dir(nullableMainNews)

Partial

모든 Property 를 Optional (nullable) 로 받을 때

// 모든 속성을 nullable 하게 
const partialMainNews : Partial<MainNews> = {};
console.log(partialMainNews)

Required

모든 Property 를 필수 Property (non nullable) 만을 선택하여 새 타입을 생성할 때 (Partial과 정 반대)


export interface News {
    readonly pressName: string;
    readonly publishingDate: Date;
    updateDate?: Date; // Required 에 의해 필수 property 가 된다.
}

// Optional Property 도 모두 not nullable 하게 한다.
//Property 'updateDate' is missing in type
const requiredMainNews : Required<MainNews> = {pressName: 'mail economy', warning: true, publishingDate: new Date()}

Tip

Interface 를 인자로 넘길 때는, 추가 Property 를 허용한다.
(기본 Property 를 모두 가지고 있는 상태라면 추가 Property 허용)

예제

interface News {
    readonly pressName: string;
    readonly publishingDate: Date;
    updateDate?: Date;
}

// 완벽한 Interface 기반 인스턴스화
const mailNews : News = {publishingDate: new Date(), updateDate: undefined, pressName: 'mail'}

function showNewsInfo(news: News) : void {
    console.dir(news);
}

// parameter 로 받을 때는 추가 프로퍼티가가 더 있어도 상관 X
const parameterNews = {publishingDate: new Date(), pressName: 'mail', publisher: 'falcon'};
// 🆗 사전에 정의하지 않은 'publisher' Property 를 추가했음에도 에러를 뿜지 않는다. 🆗
showNewsInfo(parameterNews);

/* show news info console
{
  publishingDate: 2021-07-01T02:20:03.376Z,
  pressName: 'mail',
  publisher: 'falcon'
}
*/

// 🚫 변수(객체)가 아니라 한번에 object 를 명시하여 넘기면 에러가 발생한다. 🚫
// 'publisher' does not exist in type 'News'.
showNewsInfo({publishingDate: new Date(), pressName: 'mail', publisher: 'falcon'});

🤔 대체 왜 object variable 은 되고 object literal 은 안되지⁉️

Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments.
If an object literal has any properties that the “target type” doesn’t have, you’ll get an error.

- Typescript Handbook

👉 변수에 할당되지 않은 object literal 은 자동으로 타입체크가 이뤄진다.
↔️ object variable 은 그렇지 않다.

const parameterNews : News = {publishingDate: new Date(), pressName: 'mail'};
const additionalNews = {...parameterNews, publisher: 'falcon'};
// object literal : type check
showNewsInfo({...parameterNews, publisher: 'falcon'}); // 🚫 error occured!
// object variable : not type check (can pass another property)
showNewsInfo(additionalNews); // 🆗 

⚠️ any 타입은 트랜스파일 타입체크를 피할 수 있다.
(보통, 예상이 불가능한 타입을 받을 때 사용)

📝 결론

  • type은 computed value 가능 interface는 불가능.
  • 어차피 객체에서만 쓰는 용도라면 interface 를 쓰는 것이 훨씬 낫다.
  • interface 끼리 합성은 캐싱이 일어난다. type은 일어나지 않는다.

🔗 Reference

profile
I'm still hungry

0개의 댓글