타입스크립트

타입스크립트

코드를 보다 안전하게 만드는데 도움주는 정적 타입 언어

  • 코드가 실행되는(런타임) 시점이 아닌 코드가 컴파일되는 시점에 타입을 체크하는 자바스크립트 슈퍼셋

  • 브라우저에서 타입스크립트를 이해하지 못하기 때문에 브라우저가 이해할 수 있는 자바스크립트로 트랜스파일 필요

타입 안전성

정적 타입 체킹

  • 자바스크립트는 약타입 언어로 변수에 대해 고정된 데이터 타입을 강제하지 않음

  • 타입스크립트는 변수 타입이 선언되면 변경되지 않는 강타입 언어

  • 타입스크립트는 해당 코드를 자바스크립트로 컴파일 할 때 코드에 이슈가 있음을 감지함

    • 이는 안정성과 예측성이라는 이점을 줌

    • 잠재적인 타입 관련 에러를 런타임이 아닌 개발 중에 잡아낼 수 있게됨

구성 린팅

tsconfig.json

  • 타입스크립트 구성을 커스텀하고, 컴파일러가 프로젝트 컴파일하는데 사용하는 옵션을 안내함

  • target: 대상 ESCMA 스크립트 버전

  • module: 모듈 시스템. CJS, ESM

  • jsx: JSX 파일 처리 메서드

  • outDir: 컴파일된 JS 파일을 저장할 디렉토리

  • rootDir: 입력 파일의 루트 디렉토리

  • strict: 모든 엄격 타입 옵션을 활성화하는 플래그

    • noImplictAny: 타입을 갖지 않는 모든 변수, 추론할 수 없는 매개변수에 명시적으로 타입선언을 하지않으면 에러 처리

    • strictNulLChecks: 엄격한 null, undefined 체크를 강제

    • ...

  • esModuleInterop: 생성된 코드에서 ES6 스타일 임포트/익스포트 허용하는 설정

  • skipLibCheck: 선언 파일에 대한 타입 체킹을 건너뛰는 플래그

  • forceConsistentCasingInFileNames: 파일 이름의 대소문자 일관성을 보장하는 체크 옵션

  • include: 프로그램에 포함할 파일명 혹은 패턴 배열

  • exclude: include를 해결할 때 제외할 파일명 혹은 패턴 배열

React + TS

children 타이핑

children은 특별한 prop, 상위에서 하위로 JSX를 전다할 때 사용

  • 기본적으로 children prop은 모든 타입이 될 수 있음

    • 때로는 특정 타입의 요소만 받도록 하는 것이 유용

  • React.ReactNodechildren prop에 사용할 수 있는 매우 일반적인 타입

    • 모든 유효한 리액트 하위 요소를 수용

    • 문자, 및 숫자와 같은 기본값

    • 리액트 컴포넌트

    • 들을 포함하는 배열이나 프래그먼트 등

  • React.ReactElement는 보다 구체적인 타입으로 JSX를 통해 생성된 리액트 컴포넌트 객체를 나타냄

    • 문자열, 숫자, 배열 이 아닌 단일 리액트 컴포넌트가 되도록 제한할 때 유용

Enum

관련된 값의 집합을 조직화

  • 유사한 분류에 속하는 값들을 그루핑하여 코드를 보다 직관적으로 만듦

  • 결과적으로 값이 하나의 중앙에서 관리되기 때문에 유지보수 쉬움

  • enum 키워드 대신 as const 어서션을 이용해서 비슷하게 사용 가능

const status = {
  IDLE: 'IDLE',
  LOADING: 'LOADING',
  SUCCESS: 'SUCCESS',
  ERROR: 'ERROR',
} as const;

type Status = typeof status[keyof typeof status];

선언 파일

타입스크립트로 작성되지 않은 모듈 혹은 라이브러리 타입을 선언한 파일

  • .d.ts확장자를 가지고 구현 코드가 없는 함수, 클래스, 변수에 관한 타입 정보만을 포함함

  • DefinitelyTyped : 널리 알려진 다양한 자바스크립트 라이브러리에 대한 고품질 타입스크립트 선언 파일을 포함하고 있는 저장소

    • 커뮤니티가 주도적으로 관리하고 있어 누구나 기여할 수 있음

커스텀 선언 파일`

  • .d.ts 파일을 만들어 타입 정의를 수동으로 작성

  • tsconfig.json에 include 옵션에 포함시켜야함

declare module 'library' {
  export function add(
    a: number,
    b: number
  ): number;
  
  export function subtract(
    a: number,
    b: number
    ): number;
}

API 결과 타입 자동 생성

수작업으로 유지보수하는 것은 API와 앱 사이의 불일치를 만들고, 결과적으로 런타임 에러를 발생시킴

  • 타입을 자동 생성함으로써 앱 타입이 항상 API와 동기화되는것을 보장 가능

  • 관리되지 않은 오래된 타입으로 인한 버그가 발생할 가능성을 줄인다.

GraphQL

GraphQL은 스키마, 즉 데이터 구조가 이미 잘 정의되어있음

  • GraphQL은 강타입 언어

  • 스키마는 데이터의 형태, 관련된 타입, 이들 사이의 관계를 기술하는 계약을 제공하기 때문

  • GraphQL Code Generator

    • 실행하면 스키마를 기준으로 GraphQL 객체, 쿼리, 변형에 대한 타입을 생성

  • GraphQL API와 상호작용할 떄 타입 안정성 보장

// 스키마 예시
type User {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User
}

type Mutation {
  createUser(name: String!): User!
}
export type Scalars = {
  ID: { input: string; output: string }
  String: { input: string, output: string }
}

export type User = {
  __typename?: 'User';
  id: Scalars['ID'];
  name: Scalars['String'];
}

export type Query = {
  __typename?: 'Query';
  getUser?: Maybe<User>;
}

export type Mutation = {
  __typename?: 'Mutation';
  createUser?: Maybe<User>;
}

export type QueryGetUserArgs = {
  id: Scalars['ID'];
}

export type MutationCreateUserArgs = {
  name: Scalars['String'];
}

REST

GraphQL 같이 강타입 스키마를 갖지 않기 때문에 다소 어려움

  • API가 OpenAPI 같은 명세를 사용해서 기술되어있다면 이를 사용해 타입을 생성할 수 있다.

  • OpenAPI 명세로부터 타입을 생성할 수 있는 도구로 openapi-generator

YAML을 사용해 작성한 OpenAPI 3.1.0 명세
openapi: 3.1.0
info:
  title: User API
  version: 1.0.0
paths: 
  /user:
    get:
      operationId: getUser
      parameters:
        - name: id
          in: query
          schema:
            type: string
          response:
            '200':
              description: Successful response
    post:
      operationId: createUser
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
        response:
          '201':
            description: User created
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
        name:
          type: string

RESTful API를 사용해 자동 생성한 타입
export interface User {
  id: string;
  name: string
}

export interface GetUserParameters {
  id: string
}

export interface CreateUserBody {
  name: string
}

마이그레이션

Last updated