추론 규칙
JSON 값의 종류를 그대로 TS 타입으로 옮깁니다. 문자열→string, 숫자→number, 불리언→boolean, null→null. 객체는 키 이름을 PascalCase로 바꿔 별도 인터페이스로 만들고(profile → Profile), 배열은 원소 타입 뒤에 []를 붙이되 키 이름이 복수형이면 단수로 바꿔 원소 타입 이름을 정합니다(items → Item[]). 같은 이름이 겹치면 숫자를 붙입니다. 변환은 브라우저에서만 처리됩니다.
배열 원소 병합과 optional
배열 안의 객체들을 하나의 타입으로 합칩니다. 모든 원소에 있는 키는 필수, 일부 원소에만 있는 키는 ?를 붙여 선택 속성으로 표시합니다. 같은 키의 값 타입이 원소마다 다르면(1과 "1") number | string 유니온이 됩니다. [1, "a", null] 같은 혼합 배열은 (number | string | null)[]로 나옵니다. 빈 배열은 원소를 알 수 없어 unknown[]이 되므로 직접 고쳐야 합니다.
interface와 type의 차이
객체 구조를 적는 용도로는 거의 같습니다. interface는 같은 이름으로 다시 선언하면 병합되고(declaration merging) 클래스가 implements하기 좋으며, type은 유니온·튜플·조건부 타입 같은 표현이 가능합니다. 팀 규칙이 없다면 객체는 interface, 유니온은 type으로 쓰는 것이 일반적입니다. 이 도구는 루트가 객체가 아니면(배열·원시값) 항상 type으로 출력합니다.
생성 결과를 그대로 믿으면 안 되는 경우
샘플 하나에 null이었던 값은 실제로는 문자열일 수 있고, 샘플에서 항상 있었던 키가 실제로는 가끔 빠질 수 있습니다. 날짜 문자열은 string으로만 나오며 Date로 바꾸는 것은 런타임 파싱의 몫입니다. 숫자 ID가 253을 넘으면 JSON.parse 단계에서 이미 정밀도가 깨지므로 타입과 별개로 문자열 처리가 필요합니다. 생성 결과는 출발점으로 쓰고, 가능하면 OpenAPI 스키마나 서버 측 타입 정의를 기준으로 삼는 것이 안전합니다.
자주 묻는 질문
키 이름에 하이픈이나 공백이 있어요.
TS 식별자로 쓸 수 없는 키는 "content-type"처럼 따옴표로 감싸서 출력합니다. 접근할 때는 obj["content-type"] 형태로 써야 합니다.
같은 구조의 객체가 여러 곳에 있는데 타입이 따로 생겨요.
이 도구는 키 이름 기준으로 타입을 만들고 구조가 같아도 합치지 않습니다. 중복이면 하나만 남기고 나머지 참조를 바꾸면 됩니다.
enum이나 리터럴 타입으로 만들 수 있나요?
값이 "active" | "inactive" 같은 리터럴인지 임의 문자열인지는 샘플만으로 알 수 없어 string으로 둡니다. 필요하면 생성 후 직접 좁히세요.