본문으로 건너뛰기

JSON 스키마에서 TypeScript 정의로 변환 — Numio

json-schema-to-typescript로 JSON Schema를 TypeScript interface로 컴파일합니다. "required"에 없는 속성은 선택적이 되고, additionalProperties가 false가 아닌 객체에는 인덱스 시그니처가 붙습니다.

API가 JSON Schema 파일을 공개하고 있고, 이를 사용하는 클라이언트 코드용으로 대응하는 interface가 필요할 때.

JSON Schema

TypeScript

이럴 때 사용하세요

  • API가 JSON Schema 파일을 공개하고 있고, 이를 사용하는 클라이언트 코드용으로 대응하는 interface가 필요할 때.
  • 스키마로 검증하는 설정 파일이 있고, 설정을 불러오는 곳에서 타입 검사를 받고 싶을 때.

사용 방법

  1. JSON Schema 패널에 JSON Schema를 붙여 넣습니다. "title"이 interface 이름이 되며, 없으면 루트 이름은 MySchema입니다.
  2. 입력하는 대로 브라우저에서 변환됩니다. 페이지에는 설정이 없고 배너 주석도 추가하지 않습니다.
  3. TypeScript 패널에서 interface를 복사합니다. 페이지가 Prettier로 포맷하므로 들여쓰기는 공백 두 칸이고 세미콜론은 없습니다.

JSON Schema

{
  "title": "Address",
  "type": "object",
  "properties": {
    "street": { "type": "string", "minLength": 1 },
    "zip": { "type": "string", "pattern": "^[0-9]{5}$" },
    "country": { "enum": ["US", "CA"], "default": "US" },
    "unit": { "type": ["integer", "null"] },
    "lines": { "type": "array", "items": { "type": "string" }, "maxItems": 3 },
    "geo": { "type": "object", "required": ["lat", "lng"],
      "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } }
  },
  "required": ["street", "zip"]
}

TypeScript interface

export interface Address {
  street: string
  zip: string
  country?: "US" | "CA"
  unit?: number | null
  lines?: [] | [string] | [string, string] | [string, string, string]
  geo?: {
    lat: number
    lng: number
    [k: string]: unknown
  }
  [k: string]: unknown
}

세부 정보 및 제한 사항

"additionalProperties": false가 없는 객체에는 [k: string]: unknown이 붙으므로, 타입에서 추가 키가 계속 허용됩니다.

배열의 maxItems는 예시의 "lines"처럼 튜플 유니온으로 펼쳐집니다.

#/definitions/Tag 같은 로컬 $ref는 별도로 export되는 interface가 됩니다.

페이지는 세미콜론 없는 설정으로 결과를 Prettier에 통과시키며, 이때 "US" | "CA" 같은 유니온을 감싼 불필요한 괄호도 제거됩니다.

FAQ

null 값은 어떤 타입이 되나요?

"type": ["integer", "null"]은 (number | null)이 됩니다. integer와 number는 모두 number로 매핑됩니다.

[k: string]: unknown을 없애려면 어떻게 하나요?

각 객체 스키마에 "additionalProperties": false를 추가하면 인덱스 시그니처가 생략됩니다.

루트 interface 이름은 어떻게 정해지나요?

스키마의 "title"을 PascalCase로 바꾼 값입니다("Example Schema" → ExampleSchema). title이 없으면 MySchema입니다.

스키마가 서버로 전송되나요?

아니요. json-schema-to-typescript의 compile 함수가 이 페이지의 브라우저에서 실행됩니다.

사양 및 참고 자료