JSON → TypeScript 생성기

JSON에서 TypeScript 인터페이스를 자동 생성. 중첩 객체, 배열, 유니언 타입, 선택적 속성 지원. 브라우저에서 처리, 무료.

  • 브라우저에서 처리
  • 데이터가 브라우저 밖으로 나가지 않습니다
  • 무료 · 회원가입 불필요
유효한 TypeScript 이름을 입력하세요. 비워 두면 RootObject를 사용합니다. 변경 후 TypeScript 생성을 클릭해 적용하세요.
생성되는 모든 객체 속성에 ?를 붙입니다. 꺼져 있어도 배열의 일부 객체에 없는 필드는 선택적입니다. TypeScript 생성을 클릭해 적용하세요.
객체 선언에 interface 대신 type을 사용합니다. 기본 타입의 루트 값은 항상 type을 사용합니다. TypeScript 생성을 클릭해 적용하세요.
현재 JSON, 루트 이름, 옵션으로 즉시 생성합니다. 이름이나 옵션을 바꾼 뒤 클릭해 적용하세요. Ctrl/⌘+Enter로도 생성할 수 있습니다.
JSON 입력을 중첩 객체, 배열, null이 포함된 예시로 바꿉니다. 현재 루트 이름과 옵션으로 즉시 생성합니다.
JSON, 출력, 상태를 지우고 루트 이름과 두 옵션은 유지합니다. 도구 안에서 Ctrl/⌘+L을 누르면 루트 이름도 지웁니다.
주석이나 끝 쉼표가 없는 유효한 JSON을 입력하세요. 입력을 멈춘 뒤 300밀리초 후 생성합니다. JSON이 잘못되면 출력을 지우고 오류를 표시합니다.
TypeScript 출력
현재 표시된 TypeScript 출력 전체를 복사합니다. 출력이 비어 있으면 복사하지 않습니다.

JSON을 입력하거나 예시를 불러와 TypeScript를 생성하세요.

예시·자세한 설명·자주 묻는 질문 실제 출력이 있는 예시, 다른 도구와의 차이, 자주 묻는 질문.

타입 추론 규칙

  • null → 선택적 null(field?: null)
  • 문자열 → string
  • 숫자 → number
  • 불리언 → boolean
  • 빈 배열 → unknown[]
  • 객체 배열 → 병합된 인터페이스 + ItemName[]
  • 혼합 기본 타입 배열 → 유니언 타입(예: (string | number)[])
  • 중첩 객체 → 별도의 명명된 인터페이스

예시

다음 JSON을 입력하면:

{"user": {"name": "Alice", "age": 30}, "tags": ["admin", "user"]}

다음과 같이 생성됩니다:

interface RootObject {
  user: User;
  tags: string[];
}

interface User {
  name: string;
  age: number;
}

예시: API 응답

{
  "user": {
    "id": 42,
    "name": "Alice",
    "email": "alice@example.com",
    "roles": ["admin", "editor"],
    "preferences": { "theme": "dark", "notifications": true },
    "lastLogin": null
  },
  "pagination": { "page": 1, "perPage": 20, "total": 143 }
}

에서 다음이 생성됩니다:

interface RootObject {
  user: User;
  pagination: Pagination;
}

interface User {
  id: number;
  name: string;
  email: string;
  roles: string[];
  preferences: Preferences;
  lastLogin?: null;
}

interface Preferences {
  theme: string;
  notifications: boolean;
}

interface Pagination {
  page: number;
  perPage: number;
  total: number;
}

루트 인터페이스가 맨 앞에 오고, 중첩 인터페이스는 발견된 순서대로 이어집니다. null 값은 null 타입으로 쓰이고 선택적 속성이 됩니다. 샘플 하나로는 값이 있을 때의 타입을 알 수 없기 때문입니다. API 문서를 확인한 뒤 lastLogin: string | null처럼 고치세요.

예시: 모양이 다른 요소가 섞인 배열

{
  "items": [
    { "id": 1, "name": "a", "tags": [] },
    { "id": 2, "price": 9.5, "tags": ["x", 1] }
  ],
  "messages": [
    { "type": "text", "content": "hi" },
    { "type": "image", "url": "/a.png" }
  ]
}

에서 다음이 생성됩니다:

interface RootObject {
  items: ItemsItem[];
  messages: MessagesItem[];
}

interface ItemsItem {
  id: number;
  name?: string;
  tags: (unknown[] | (string | number)[]);
  price?: number;
}

interface MessagesItem {
  type: string;
  content?: string;
  url?: string;
}

배열 안의 객체는 모두 병합되며, 일부 요소에만 있는 키에는 ?가 붙습니다. messages는 사실 type으로 구분되는 두 가지 모양입니다. 병합된 인터페이스는 “url이 있는 text 메시지” 같은 잘못된 조합도 허용하므로 구별된 유니언 타입으로 다시 쓰세요(TypeScript Handbook: Narrowing):

type Message =
  | { type: "text"; content: string }
  | { type: "image"; url: string };

예시: 같은 키 이름의 객체가 둘인 경우

{
  "order": { "id": "A-1001", "meta": { "createdBy": "alice", "source": "web" } },
  "payment": { "status": "paid", "meta": { "provider": "stripe", "fee": 0.3 } }
}

생성 결과

interface RootObject {
  order: Order;
  payment: Payment;
}

interface Order {
  id: string;
  meta: Meta;
}

interface Meta {
  createdBy: string;
  source: string;
}

interface Payment {
  status: string;
  meta: PaymentMeta;
}

interface PaymentMeta {
  provider: string;
  fee: number;
}

order.meta는 Meta라는 이름을 받습니다. payment.meta는 필드가 달라 별도 인터페이스가 되며, 부모 이름을 앞에 붙여 PaymentMeta가 됩니다. order.meta와 필드가 같다면 둘이 Meta를 함께 씁니다. 둘을 모든 필드가 선택적인 Meta 하나로 합치면 어느 API도 돌려주지 않는 객체까지 받아들이므로, 모양마다 타입을 따로 둡니다. 이름이 이미 쓰였으면 번호를 붙입니다(Meta2). 중첩된 키가 루트와 이름이 같아도 루트는 지정한 이름을 유지합니다.

직접 다듬을 부분

  • null 필드: ?: null을 실제 타입과 | null로 바꿉니다.
  • 빈 배열: []은 unknown[]이 되므로 요소 타입을 채웁니다.
  • 날짜: ISO 8601 문자열과 Unix 타임스탬프는 각각 string, number로 남습니다.
  • 식별자로 쓸 수 없는 키(user-name, 2fa)는 따옴표로 감싸 출력되며 TypeScript에서 유효합니다.
  • PaymentMeta, Meta2 같은 이름은 JSON 키에서 만들어집니다. 용도에 맞게 이름을 바꾸세요.
  • 올바른 타입 이름이 되지 않는 키(2fa, 빈 키)는 인터페이스 이름 앞에 T를 붙입니다(T2fa). 속성 자체는 원래 키를 따옴표로 감싸 씁니다.

제한 사항

  • 입력은 유효한 JSON이어야 합니다(주석, 끝 쉼표 불가). 오류 메시지에 위치가 표시됩니다.
  • 타입은 붙여넣은 샘플에서만 결정됩니다. 샘플에서는 문자열이지만 실제로는 가끔 숫자인 필드도 string으로 남습니다.
  • interface 대신 type 사용을 선택하면 각 선언이 type Name = { ... }로 출력되지만 상태 표시는 “인터페이스” 그대로입니다.

FAQ

이 도구는 무엇을 생성합니까?

JSON 객체에서 TypeScript interface(또는 type alias) 선언을 생성합니다. 중첩된 객체는 각각 별도의 명명된 인터페이스가 되고, 배열 내 혼합 타입은 유니언 타입이 됩니다.

중첩 객체는 어떻게 처리됩니까?

각 중첩 객체 필드는 필드 키의 PascalCase 이름을 가진 별도의 인터페이스로 추출됩니다. 예를 들어 'address' 필드는 'Address' 인터페이스가 되고, 부모 인터페이스는 그 이름으로 참조합니다.

객체 배열은 어떻게 처리됩니까?

배열에 객체가 포함된 경우 모든 객체의 필드가 하나의 아이템 인터페이스로 병합됩니다. 일부 객체에만 있는 필드는 선택적으로 표시됩니다.

'Make properties optional' 옵션은 무엇입니까?

체크하면 생성된 모든 인터페이스의 모든 속성에 '?'가 붙어 선택적이 됩니다. 불완전한 데이터를 받을 가능성이 있거나 느슨한 타입 정의가 필요할 때 유용합니다.

interface와 type의 차이는 무엇입니까?

둘 다 객체 형태를 선언할 수 있습니다. 'interface'는 선언 병합을 지원하며 객체 타입의 관용적인 표현입니다. 'type'은 더 유연하여 기본 타입, 유니언 타입, 튜플도 표현할 수 있습니다. 'Use type instead of interface'로 전환할 수 있습니다.

데이터가 서버로 전송됩니까?

아니요. 전체 타입 추론 엔진이 브라우저에서 실행됩니다. 데이터는 기기 밖으로 나가지 않습니다.