콘텐츠로 건너뛰기

🧬 JSON → 타입 정의 변환

JSON을 붙여넣으면 TypeScript / PHP / Python / Go / Rust 타입 정의를 자동 생성합니다. 중첩된 객체와 배열을 지원.

완전 무료 가입 불필요 브라우저 완결 5 개 언어 다크 모드

💡 사용 팁

• 중첩된 객체는 자동으로 별도 타입으로 추출됩니다.

• 배열 요소에서 타입을 추론합니다. 빈 배열은 any[] / []interface{} 등이 됩니다.

• null은 string | null 같은 optional / nullable로 처리됩니다.

• 루트 타입 이름은 위 입력 필드에서 변경할 수 있습니다.

🔗 관련 도구

📖 자주 걸리는 지점

JSON 을 붙여 넣으면 TypeScript / PHP / Python / Go / Rust / Kotlin / Swift 의 타입 정의를 생성합니다. 중첩된 오브젝트는 별도의 타입으로 추출되고 배열의 요소에서도 타입을 추론합니다. 처리는 브라우저 안에서 끝납니다. 추론할 수 있는 것은 건넨 샘플에 나타난 형태뿐입니다 — API 의 응답 한 건은 그때 돌아온 형태이지 사양이 아닙니다. 생성물은 완성품이 아니라 손으로 고치기 위한 출발점이라고 생각하세요.

사례 무슨 일이 일어나는가 어떻게 하면 되는가
샘플 한 건에서 만든 타입이 프로덕션에서 맞지 않는다 추론은 본 것이 전부라는 전제로 동작합니다. 따라서 그 샘플에 나타나지 않은 필드는 타입에 존재하지 않고 우연히 값이 들어 있던 필드는 필수로 다뤄집니다. 실제 API 는 검색 결과가 0 건일 때, 에러일 때, 권한이 부족할 때, 오래된 레코드일 때 각각 다른 형태를 반환합니다. 특히 위험한 것이 enum 적인 필드로 샘플에 "active" 밖에 없으면 타입은 "active" 라는 리터럴 타입이 되고 "archived" 가 오는 순간 타입이 거짓말이 됩니다. 복수의 응답을 통과시키세요 — 정상 · 빈 결과 · 에러 · 경곗값의 네 패턴을 최소한으로 하고 생성된 타입을 맞춰 보면 어느 필드가 정말로 필수인지가 보이기 시작합니다. OpenAPI 사양이 있다면 그쪽에서 생성하세요openapi-typescriptoapi-codegen돌아올 수 있는 형태를 사양으로 갖고 있으므로 샘플에서의 추론과는 신뢰성이 다릅니다. 그리고 생성한 타입은 반드시 한 번 읽으세요 — 전 필드가 필수, enum 이 리터럴 하나인 타입이 나왔다면 그것은 샘플이 한 건이었다는 신호입니다.
빈 배열이나 null 에서는 타입이 정해지지 않는다 "tags": [] 라는 값에서는 요소의 타입을 알 방법이 없습니다 — 결과는 any[] · []interface{} · List<Any> 같은 무엇이든 들어가는 타입이 되어 타입 검사의 혜택이 완전히 사라집니다. null 도 마찬가지로 정보가 부족합니다 — "deleted_at": null 이 늘 null 인지 이번만 null 인지는 이 한 건에서는 판별할 수 없습니다. 나아가 근본적인 문제로 JSON 에서는 키가 존재하지 않는 것과 키의 값이 null 인 것을 구별할 수 있지만 많은 언어의 타입 시스템에서는 이 구별이 모호해집니다 — TypeScript 의 ?:| null 은 별개입니다. 빈 배열을 포함하는 응답은 요소가 들어 있는 다른 응답도 통과시키세요 — 한 건이라도 요소가 있으면 타입이 정해집니다. 그것을 손에 넣을 수 없다면 그 배열의 타입만 손으로 쓰세요 — 생성물을 그대로 쓰는 것이 아니라 9 할을 자동화하고 나머지를 채우는 것 이라고 생각하면 이 작업은 부담이 되지 않습니다. null 의 취급은 API 의 문서를 보는 수밖에 없습니다 — 키가 없음 과 null 을 구별하는 API 라면 TypeScript 에서는 deleted_at?: string | null 처럼 양쪽을 쓰는 것이 정확합니다. 망설여지면 느슨한 쪽으로 기울이세요 — 타입이 느슨하고 실행 시에 검사하는 편이 타입이 엄격하고 실행 시에 떨어지는 것보다 안전합니다.
숫자의 타입이 언어에 따라 의미를 바꾼다 JSON 의 숫자는 한 종류밖에 없습니다 — 정수와 소수의 구별도 정밀도의 지정도 없습니다. 따라서 생성 쪽은 언어마다 무언가를 고를 수밖에 없어 Go 라면 float64, Rust 라면 i64f64, TypeScript 라면 number 가 됩니다. 여기서 위험한 것이 ID 입니다큰 정수를 float64number 로 받으면 2 의 53 제곱을 넘은 시점에 정밀도가 떨어져 값이 조용히 바뀝니다. 90071992547409939007199254740992 가 되어도 에러는 나지 않습니다. 날짜 같은 문자열도 당연히 string 그대로입니다. ID · 금액 · 일시는 생성 후에 반드시 손으로 타입을 고치세요. ID 는 문자열로 다루는 것이 가장 안전합니다 — 계산하지 않는 값을 숫자로 가질 이유는 없습니다(실제로 Twitter 나 Discord 의 API 는 큰 ID 를 문자열로 반환합니다). 금액은 부동소수점으로 하지 마세요0.1 + 0.20.3 이 되지 않는 것과 같은 이유로 최소 단위의 정수나 언어의 Decimal 타입을 쓰세요. 일시는 string 이 아니라 각 언어의 일시 타입으로 고치면 타임존의 취급을 타입이 강제해 줍니다. 생성한 타입을 한 줄씩 읽고 이 값으로 계산하는가를 자문하세요 — 계산하지 않는다면 문자열로 상관없습니다.

생성한 타입을 믿을 수 있는 경계라고 생각하지 마세요. 특히 TypeScript 의 타입은 컴파일 시에만 존재하고 실행 시에는 아무것도 검증하지 않습니다await res.json() as User 라고 쓰면 실제로 돌아온 것이 무엇이든 컴파일러는 User 라고 믿습니다. 이는 타입 시스템의 결함이 아니라 경계에서의 검증은 다른 레이어의 일이라는 설계입니다. API 의 응답이나 폼의 입력처럼 밖에서 오는 데이터에는 zodvalibot 같은 런타임 검증을 반드시 넣으세요 — 스키마에서 타입을 도출할 수 있으므로 이중 관리도 되지 않습니다. Go 의 json.Unmarshal 이나 Rust 의 serde 는 실제로 검증하므로 그나마 안전하지만 기본적으로는 알 수 없는 필드를 조용히 버립니다 — Go 라면 DisallowUnknownFields, Rust 라면 #[serde(deny_unknown_fields)]API 의 변경을 알아챌 수 있게 됩니다.

📖 사용법

  1. 1
    JSON 입력 또는 붙여넣기
    왼쪽 입력란에 JSON을 붙여넣으세요. 샘플 버튼으로 예시 데이터를 빠르게 확인할 수 있습니다.
  2. 2
    대상 언어 선택
    TypeScript, PHP, Python, Go, Rust, Kotlin, Swift 중 언어를 선택하고 루트 타입 이름을 변경하세요.
  3. 3
    타입 정의 복사하여 사용
    오른쪽에 자동 생성된 타입 정의가 표시됩니다. 복사 버튼으로 클립보드에 복사하세요.

❓ 자주 묻는 질문

중첩된 객체는 어떻게 처리되나요?
중첩된 객체는 자동으로 별도 타입으로 추출되어 참조로 사용됩니다.
null 필드는 어떻게 타입이 지정되나요?
null 필드는 optional/nullable로 처리됩니다. 언어에 따라 Optional, ?, 포인터 타입 등으로 변환됩니다.
최상위 JSON 배열도 지원하나요?
네. 루트가 배열인 경우 자동으로 { items: [...] }로 래핑하여 타입을 생성합니다.
🐛 이 도구에서 문제가 발생했나요?

무료 · 가입 불필요. 재현 절차만이라도 도움이 됩니다. 보고는 운영자에게 직접 전달되어 개선에 사용됩니다.

※ 재현을 위해 브라우저 정보 (UA / 화면 / 언어 / URL) 가 자동 전송됩니다