TypeScript Utility Types(1)

이지훈·2022년 10월 31일
0
post-thumbnail

TypeScript란?

흔히들 많이 아는 JavaScript는 브라우저 환경에서 컴파일 되는 언어이다.
이 JavaScript를 이용하여 웹 페이지를 dynamic 즉, 동적으로 만들 수 있다.
Js는 흔히 말하는 쉬게 배울 수 있는 언어이다. 실제로 Js를 만들기 위해서 10일(?) 정도 밖에 걸리지 않았다고 한다.
하지만 이러한 사실 때문에 Js는 매우 불안정한 언어가 되어 버리고 만다. 실제 Js를 이용하여 개발을 해봤으면 느끼겠지만 변수의 type, 함수의 return type, 함수의 parameter의 type과 같은 type에 매우 관대한 편이다.
오죽하면 Js는 123 == '123'을 true로 반환해버린다.

이 밖에도 여러 불안정한 요소가 많지만 오늘의 주제는 TypeScript이기 때문에 다음시간에 더 알아보도록 하자.
위에서 말한 불안정성과 개발시의 sideEffect를 줄이기 위해서 바로 TypeScript가 나오게 되었다.
또한 Ts는 개발단계에서 오류를 검사해서 잡아준다.
사실 실제 개발시에 TypeScript를 적용하게 된다면 초기 개발시에 Js를 사용하는 것보다 더욱 많은 시간을 투자해야 한다. 하지만 프로젝트의 안정성과 유지보수의 효율성을 위해 최근에는 많은 실무에서 Ts를 적용하고 있다.

Utility Types?

사실 Ts는 Js를 잘 다룬다면 쉽게 배울 수 있는 언어(?)이다. 하지만 자칫 잘못 설계를 한다면 코드가 매우 길어지고 더러워 질수가 있다.
그래서 조금 능숙한 개발자라면 기존의 Type을 조합하여 새로운 Type을 만들어 사용하곤 한다.
그럴때 사용하는 것이 바로 TypeScript Utility Type이다.
이것만 잘 사용해도 코드가 매우 간결해지고 깔끔해질것이다.

프로젝트 생성

npx create-react-app@latest --template=typescript
// @latest는 create-react-app을 최신버전으로 받기 위함

Partial<Type>

Partial<Type>은 <>안에든 Type 잡합의 프로퍼티를 선택적으로 선택하여 사용할 수 있다는 표현이다.
즉 Partial<Type>은 Type의 하위 잡합이 되는것이다.
예시 코드

interface PatialExam {
  name : string,
  email : string
}

function App() {

  const exam1 : Partial<PatialExam> = {
    name : 'jihoon'
  }

  const exam2 : Partial<PatialExam> = {
    email : "jihoon@gamil.com"
  }

  const exam3 : Partial<PatialExam> = {
    language : 'typescript' //Type Error!!!!!!!
  }

  return (
    <div className="App">
      <p>TypeScript Utility Types</p>
    </div>
  );
}

사실 말보다는 코드를 보고 이해하는것이 더 빠를듯하다 ㅎㅎ

Required<Type>

Required<Type>은 Type의 모든 프로퍼티를 필수로 다 사용해야하는 표현입니다.
따라서 Partial<Type>의 반대 표현입니다.
예시 코드

interface RequiredExam {
    name ?: string,
    email ?: string
  }
  
  function Required() {
  
    const exam1 : Required<RequiredExam> = {
      name : 'jihoon' //Type Error, not exist email
    }
  
    const exam2 : Required<RequiredExam> = {
      email : "jihoon@gamil.com" //Type Error, not exist name
    }

    const exam3 : Required<RequiredExam> = {
        name : 'jihoon',
        email : 'jihoon@gamil.com'
    }
  
    return (
      <div className="App">
        <p>TypeScript Utility Types</p>
      </div>
    );
  }

Type의 모든 프로퍼티가 ?(optional)로 되어 있지만 Required를 사용한다면 반드시 모든 프로퍼티가 필수로 들어가야한다.

ReadOnly<Type>

ReaonlyType은 Type에 특수기능을 넣은 표현이다.
말 그대로 이미 할당된 프로퍼티의 값을 바꿀수 없음을 의미한다.
예시 코드

interface ReadOnlyExam {
    name: string;
    email: string;
}

function ReadOnly() {
    const exam1 : Readonly<ReadOnlyExam> = {
      name : 'jihoon',
      email : 'jihoon@naver.com'
    }

    exam1.name = 'jay'; //Type Error, name is Read-only

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

여기까지는 너무나도 쉽다.

Record<keys,Type>

Record<keys,Type>를 사용하면 keys는 새로운 key값이 되고 Type은 해당 key 값의 Type이 된다는 표현
예시 코드

interface RecordExam {
    name: string;
    email: string;
}

type keys = "kor" | "us" | "uk";

function ReadOnly() {
    const exam1: Record<keys, RecordExam> = {
        kor: {
            name: "지훈",
            email: "지훈@naver.com",
        },
        us: {
            name: "jay",
            email: "jay@google.com",
        },
        uk: {
            name: "kevin",
            email: "kevin@fb.com",
        },
    };

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

keys에서 | 표시는 Or(또는)의 표시이다.

Pick<Type,Keys>

Pick<Type,Keys>는 Type에서 Keys의 해당되는 프로퍼티만을 선택해서 사용한다는 표현이다.
예시 코드

interface PickExam {
    name: string;
    email: string;
    country: string;
}

type keys = "name" | "country";

function Pick() {
    const exam1: Pick<PickExam, keys> = {
        name: "jihoon",
        country: "ko",
    };

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

Type과 Keys의 순서에 유의하자!

Omit<Type,keys>

Omit<Type,keys>는 Type에서 모든 프로퍼티를 선택한 후 keys를 제외하여 사용한다는 표현이다.
예시 코드

interface OmitExam {
    name: string;
    email: string;
    country: string;
}

type keys = "name";

function Omit() {
    const exam1: Omit<OmitExam, keys> = {
        country: "ko",
        email : 'jihoon@naver.com'
    };

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

name 프로퍼티만 제외된것을 볼 수 있다.

Exclude<Type,ExcludedUnion>

Exclude<Type,ExcludedUnion>은 union type인 Type에서 ExcludedUnion을 제외하고 사용한다는 표현이다.
얼핏 Omit과 비슷해보이지만 아니다.
예시 코드

type ExcludedExam = string | boolean | (() => void)

type keys = boolean;

type ExcludedType = Exclude<ExcludedExam, keys>
//ExcludedType = string | (()=>void); 와 같다.

function Excluded() {
    const exam1: ExcludedType = 'hihi';

    const exam2: ExcludedType = () => {
        console.log('hihi');
    }

    const exam3: ExcludedType = true; //Type Error!!!

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

union type이란 앞서 살펴 봤던 |(or)를 이용해서 만든 type의 집합이다.

Extract<Type,Union>

Extract<Type,Union>은 union type인 Type 중에서 Union에 속해있는것만을 추출해서 사용한다는 표현이다.
예시 코드

type ExtractExam = string | boolean | (() => void);

type keys = boolean | Function | number;

type ExtractType = Extract<ExtractExam, keys>;
// ExtractType = boolean | (() => void) 와 같다.

function Extract() {
    const exam1: ExtractType = () => {
        console.log("hihi");
    };

    const exam2: ExtractType = true;

    const exam3: ExtractType = "jihoon"; //Type Error,can't string

    const exam4: ExtractType = 4; //Type Error, can't number

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

Union에 Type에 포함되지 않은 type이 있어도 그것은 포함되지 않는다.

NonNullable<Type>

NonNullable<Type>은 Type에서 null과 undefined를 제외하고 사용한다는 표현이다.
예시 코드

type NonNullableExam = string | boolean | (() => void) | undefined | { name : string, email : undefined};

type NonNullableType = NonNullable<NonNullableExam>;
// NonNullableType = string | boolean | Function | { name : string, email : undefined }

function NonNullable() {
    const exam1 : NonNullableType = 'jihoon';

    const exam2 : NonNullableType = true;

    const exam3 : NonNullableType = () => {
        console.log('hihi');
    }

    const exam4 : NonNullableType = undefined; // Type Error!!!

    const exam5 : NonNullableType = {
        name : 'jay',
        email : undefined
    }

    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

단, object안에 undefined인 프로퍼티가 있다고 제외되는것은 아니다!

Parameters<Type>

Parmeters<Type>은 함수 type인 Type의 parameter에서 사용된 type을 튜플 형식으로 반환한다.
예시 코드

function ParameterExamFunc1 (a : string, b : number) {
    return {
        a,b
    }
}

declare function ParameterExamFunc2(arg : {c : number}): void;

type ParameterExamType1 = Parameters<()=>string>;
// ParameterExamType1 = [];
type ParameterExamType2 = Parameters<typeof ParameterExamFunc2>;
// ParameterExamType2 = [arg : {c : number}]
type ParameterExamType3 = Parameters<typeof ParameterExamFunc1>;
// ParameterExamType3 = [a : string, b : number]

function Parameters() {
    
    return (
        <div className="App">
            <p>TypeScript Utility Types</p>
        </div>
    );
}

많이 사용되지는 않지만 간간히 사용될때가 있으니 뭔지만 기억해두자!

아직 10개의 Utitlity Type이 더 남았다. 하지만 쓰다보니 너무 길어져서 2편에서 나머지 10개를 알아보도록 하자!
마무리도 2편에서 짓는걸루~~

참조
https://www.typescriptlang.org/ko/docs/handbook/utility-types.html
https://www.w3schools.com/typescript/typescript_union_types.php

profile
안녕하세요 주니어 프론트엔드 개발자 이지훈입니다.

0개의 댓글