JSON → 타입 정의 생성기

API 응답 JSON을 붙여넣으면 TypeScript interface를 자동 생성합니다. Python·Java·Go·Kotlin 타입도 함께 지원합니다.

📁 .json 파일을 끌어다 놓거나 클릭해서 선택
파일은 브라우저에서만 읽습니다 · 최대 8MB
생성된 타입

🧠 배열 요소를 여러 개 넣을수록 추론이 정확해집니다. 어떤 요소에만 있는 키는 선택 속성으로, 값이 섞여 있으면 유니온으로 잡습니다. 구조가 같은 객체는 타입 하나를 만들어 재사용합니다.
⚠ 샘플 한 건에서 뽑은 초안입니다. 실제 API 스펙의 선택 필드·널 가능성·enum은 샘플에 안 나올 수 있으니 문서와 대조해 다듬어 쓰세요. 입력한 JSON은 브라우저 밖으로 나가지 않습니다.

JSON → 타입 정의 생성기란?

API 응답을 받아 코드에 붙일 때 가장 귀찮은 일이 타입을 손으로 옮겨 적는 것입니다. 키가 서른 개 넘는 응답을 보며 interface를 타이핑하다 보면 오타 하나로 컴파일 에러가 나고, 중첩 객체는 인터페이스를 몇 개나 더 만들어야 할지부터 고민됩니다. 이 도구는 실제 JSON 응답을 붙여넣으면 구조를 분석해 타입 정의를 통째로 만들어 줍니다. 중첩된 객체는 키 이름을 따서 별도 인터페이스로 분리하고, 배열은 요소들을 모두 비교해 공통 타입을 뽑아냅니다. 배열 요소 중 일부에만 있는 키는 선택 속성(?)으로, 값이 섞여 있으면 유니온으로 추론합니다. 같은 JSON에서 TypeScript뿐 아니라 Python dataclass·TypedDict, Java record, Go struct(json 태그 포함), Kotlin data class도 뽑을 수 있어 서버와 클라이언트가 다른 언어여도 한 화면에서 끝납니다.

사용 방법

  1. API 응답 JSON을 입력창에 붙여넣거나 .json 파일을 끌어다 놓습니다.
  2. 언어 탭에서 TypeScript·Python·Java·Go·Kotlin 중 필요한 것을 고릅니다.
  3. 루트 타입 이름을 실제 쓸 이름(예: OrderResponse)으로 바꿉니다.
  4. 선택 속성 추론·null 허용·readonly 등 옵션을 취향에 맞게 켭니다.
  5. 결과를 복사하거나 파일로 저장해 프로젝트에 붙여넣습니다.

JSON → 타입 정의 생성기 사용 가이드

실제 작업에서 이 도구를 어떻게 쓰는지, 무엇을 조심해야 하는지 정리했습니다.

타입을 손으로 옮겨 적으면 생기는 일

키가 서른 개인 API 응답을 보며 interface 를 타이핑하다 보면 두 가지가 반드시 일어납니다. 하나는 오타(created_at 을 create_at 으로) — 이건 컴파일러가 잡아 주니 그나마 낫습니다. 다른 하나가 문제인데, 귀찮아서 any 로 두거나 지금 필요한 필드만 골라 적는 것입니다.

그 순간 타입은 "응답의 모양"이 아니라 "내가 지금 쓰는 필드 목록"이 됩니다. 다음 사람이 응답에 있는 필드를 자동완성으로 찾다가 못 찾고, 이미 있는 필드를 또 추가합니다. 이 도구는 실제 응답을 통째로 넣어 전체 모양을 한 번에 뽑는 것으로 이 흐름을 끊습니다.

루트 이름을 반드시 실제로 쓸 이름(OrderResponse, UserListResult)으로 바꾸세요. Root 로 둔 채 프로젝트에 붙여넣으면 다음 API를 붙일 때 이름이 충돌합니다.

선택 속성(?) 추론의 한계 — 이게 가장 중요합니다

이 도구가 선택 속성을 판단하는 방법은 단 하나입니다. 배열 안에 같은 형태의 객체가 여러 개 있을 때, 어떤 요소에는 있고 어떤 요소에는 없는 키를 물음표로 표시합니다. 그 외의 근거는 없습니다.

뒤집어 말하면 — 샘플에 안 나온 것은 모릅니다. 스펙상 nullable 인 필드인데 마침 그날 응답에 값이 다 차 있었다면, 이 도구는 필수·비-null 로 냅니다. 코드는 컴파일되고 잘 돌아가다가, 값이 빠진 응답이 처음 오는 날 런타임에서 터집니다.

  • 가장 실전적인 요령 — 응답 하나가 아니라 목록 응답을 통째로 넣으세요. items 배열에 20건이 들어 있으면 20건을 서로 비교해 선택 속성과 유니온을 훨씬 정확하게 잡습니다.
  • 더 좋은 방법은 성격이 다른 응답 여러 건을 배열로 묶어서 넣는 것입니다. 정상 케이스, 쿠폰 없는 케이스, 취소된 케이스를 함께 넣는 식입니다.
  • "선택 속성(?) 추론"을 끄면 모든 키를 필수로 냅니다. 스펙을 이미 확실히 알고 있어서 도구의 추측을 원하지 않을 때 씁니다.
입력한 샘플나오는 타입실제로는
coupon 값이 null 인 응답 한 건null 또는 any쿠폰 객체가 올 수도 있음 — 손으로 고쳐야 함
tags 가 빈 배열인 응답 한 건any[]요소 타입을 알 수 없음 — 채워진 샘플이 필요
목록 응답 1건만모든 키가 필수스펙상 선택 필드가 섞여 있을 수 있음
status 가 "paid" 인 한 건stringpaid | shipped | cancelled 유니온일 가능성이 큼
price 가 30000 인 한 건number / int / int64소수가 오는 필드일 수 있음
통계의 "선택 속성" 숫자가 0이면, 진짜로 선택 필드가 없는 게 아니라 샘플이 한 건뿐일 가능성이 높습니다.

타입이 있으면 안전하다는 착각

TypeScript 타입은 컴파일 시점에만 존재합니다. 빌드되면 사라집니다. fetch 로 받은 JSON에 as OrderResponse 를 붙이는 것은 "이 모양일 거라고 컴파일러에게 약속"하는 것일 뿐, 실제로 그 모양인지 검사하지 않습니다.

그래서 서버가 필드 이름을 바꾸거나 null 을 보내기 시작해도 타입스크립트는 아무 말도 하지 않습니다. 화면에서 undefined 를 읽다 터지는 순간 처음 알게 됩니다. 이 도구가 만든 타입이 정교할수록 "검증됐다"는 착각이 커진다는 점이 오히려 위험합니다.

  • 경계(외부 API 응답을 받는 지점)에서는 zod·valibot 같은 런타임 검증기로 한 번 걸러 주세요. 여기서 만든 interface 는 그 스키마를 짜기 위한 밑그림으로 쓰면 됩니다.
  • 내부에서만 도는 데이터(설정 파일, 상수)라면 이 도구의 결과를 그대로 써도 충분합니다.
  • Java·Kotlin·Go는 역직렬화 단계에서 타입이 안 맞으면 대체로 예외가 납니다. 조용히 통과하는 TypeScript와 성격이 다릅니다.

언어별로 뭐가 나오나

JSON 키가 order_id 같은 스네이크 케이스면 언어 관례상 필드명은 OrderID·orderId 가 됩니다. 이름이 달라지는 순간 매핑 정보를 잃으므로, 이름이 실제로 다를 때만 애너테이션·태그를 붙입니다. 다른 직렬화 라이브러리(Gson, Moshi 등)를 쓴다면 해당 애너테이션으로 바꾸세요.

숫자는 언어에 따라 갈립니다. 관측된 값이 모두 정수면 int/long/int64/Long, 소수가 하나라도 있으면 float/double/float64/Double 로 냅니다. 금액 필드가 정수만 담긴 샘플이었다면 실제로 소수가 올 수 있는지 확인하세요.

언어형태이름이 다를 때참고
TypeScriptinterface / type aliasreadonly·export 옵션이 모두 의미 있음
Pythondataclass / TypedDictdataclass 는 frozen=True 로 불변 가능, TypedDict 는 dict 그대로 다룰 때
Javarecord@JsonProperty (Jackson)record 는 이미 불변이라 readonly 옵션이 꺼집니다
Gostructjson 태그null 허용을 켜면 포인터로 나옵니다
Kotlindata class@SerialName (kotlinx.serialization)null 허용은 물음표로 표기

붙여넣기 전 5분 체크리스트

  1. 루트 이름과 하위 타입 이름을 프로젝트 규칙에 맞게 바꿉니다. items 배열의 요소는 단수형을 추정해 Item 이 됩니다 — 뜻이 애매하면 직접 고치세요.
  2. string 으로 나온 필드 중 값의 종류가 정해진 것(status, type, grade)을 유니온·enum 으로 좁힙니다.
  3. ISO 날짜 문자열은 string 으로 나옵니다. Date 로 바꿀지 문자열로 둘지 팀 규칙을 정하세요.
  4. 큰 정수(주문번호, 스노우플레이크 ID)가 number 로 나왔다면 주의하세요. 자바스크립트 number 는 2의 53승을 넘으면 정밀도를 잃습니다. 서버가 문자열로 주는지 확인하고 string 으로 바꾸는 편이 안전합니다.
  5. 스펙 문서와 대조합니다. 문서에 있는데 샘플에 없는 필드를 손으로 추가하세요.
입력한 JSON은 브라우저 밖으로 나가지 않으므로, 운영 API의 실제 응답을 그대로 붙여넣어도 됩니다. 오히려 그래야 정확한 타입이 나옵니다.

자주 묻는 질문

중첩된 객체는 어떻게 처리되나요?

객체 안의 객체는 별도 타입으로 분리하고, 그 키 이름을 PascalCase로 바꿔 이름을 붙입니다. 예를 들어 customer 키의 객체는 Customer, items 배열의 요소는 단수형을 추정해 Item이 됩니다. 구조가 완전히 같은 객체가 여러 곳에 나오면 타입을 하나만 만들고 재사용합니다.

선택 속성(?)은 어떤 기준으로 붙나요?

배열 안에 같은 형태의 객체가 여러 개 있을 때, 어떤 요소에는 있고 어떤 요소에는 없는 키를 선택 속성으로 판단합니다. 샘플이 하나뿐이면 판단할 근거가 없으므로 모두 필수로 나옵니다. 응답 샘플을 여러 건 담은 배열을 넣을수록 추론이 정확해집니다.

값이 null이면 타입이 어떻게 되나요?

null 허용 옵션을 켜면 관측된 타입에 | null 을 붙입니다(Kotlin은 ?, Go는 포인터). 끄면 null은 무시하고 나머지 값의 타입만 사용하며, 값이 null밖에 없는 키는 any(언어별 Object/interface{}/Any)로 둡니다.

숫자는 int인가요 float인가요?

TypeScript는 number 하나로 충분하지만 Python·Java·Go·Kotlin은 구분이 필요합니다. 관측된 값이 모두 정수면 int/long/int64/Long, 소수가 하나라도 있으면 float/double/float64/Double로 냅니다. 정수만 담긴 샘플이라도 실제로는 소수가 올 수 있는 필드라면 직접 고쳐 주세요.

Go의 json 태그나 Java의 @JsonProperty는 왜 붙나요?

JSON 키가 order_id처럼 스네이크 케이스면 언어 관례상 필드명은 OrderID/orderId가 되어 이름이 달라집니다. 그 매핑을 잃지 않도록 Go는 json 태그, Java는 Jackson의 @JsonProperty, Kotlin은 kotlinx.serialization의 @SerialName을 이름이 다를 때만 붙입니다. 다른 직렬화 라이브러리를 쓴다면 해당 애너테이션으로 바꿔 주세요.

생성된 타입을 그대로 믿어도 되나요?

샘플 하나에서 추론한 결과이므로 어디까지나 초안입니다. 실제 API 스펙에 있는 선택 필드, enum 값, 널 가능성은 샘플에 안 나올 수 있습니다. 스펙 문서와 대조해 다듬어 쓰는 것을 권합니다.

입력한 JSON이 서버로 전송되나요?

아니요. 파싱과 타입 생성 모두 브라우저 안에서만 실행되며, JSON 내용이 서버로 전송되거나 저장되지 않습니다. 실제 응답 데이터를 붙여넣어도 안전합니다.