마침내 제가 API 타입을 손수 쓰는 것을 멈추게 만든 버그는 당황스러울 정도로 작았습니다. 반환된 지불 엔드포인트 discount: null 없는 고객을 위해 입력했습니다 discount: number 인터페이스를 작성하는 동안 내가 본 하나의 응답은 할인과 고객 일이 있었기 때문에. TypeScript 완벽하게 행복했다. 컴파일러는 I & # 39;d 에 대해 거짓말을 알 방법이 없었다. 삼주 후 a .toFixed(2) 해당 분야에서는 내 테스트와 송장에 가장 중요한 사용자 하위 집합을 위한 생산이 시작되었습니다.
그것은 손으로 API를 입력 할 때의 전체 문제입니다: 당신은 당신이 무엇을 입력합니다 믿다 엔드포인트가 돌아오고,컴파일러는 현실보다는 당신의 믿음을 충실하게 시행합니다. TypeScript 가 다운스트림에 제공하는 모든 보증은 직접 손으로 쓴 인터페이스만큼만 좋으며,도구 체인에는 실제 응답과 비교하여 확인하는 것이 전혀 없습니다. 당신은 안전성이 전혀 없는 정적 타이핑의 모든 의식을 얻게 되는데,이는 틀림없이 전혀 유형이 없는 것보다 더 나쁩니다. - 적어도 유형이 지정되지 않은 코드는 의심을 불러일으킵니다.
실제 페이로드에서 타입을 생성하면 방향이 뒤집힙니다. 도형이 무엇이라고 생각하는지 설명하는 대신 서버가 실제로 보낸 응답을 받아 그로부터 도형을 도출합니다. 출력은 기계적입니다: 낙관주의 없음,존재한다는 것을 잊은 필드 없음 number 데이터가 말하는 곳 number | null. 나는 [Toolz.dev](/를 구축하고 브라우저 기반 넣어 JSON에서 TypeScript로 변환합니다 여기에서 이를 수행하지만 이 가이드는 추론 규칙 자체, 즉 생성기가 무엇을 알아낼 수 있는지, 무엇을 추측할 수 있는지, 그리고 여전히 생각해야 하는 위치에 관한 것입니다.
TL;DR: JSON 을 TypeScript 로 변환하려면,각각의 key's 타입을 그 값으로부터 추론한다 (
string,number,boolean,null), 중첩된 객체를 자신의 명명된 인터페이스로 추출하고,객체의 배열을 일부 멤버에서 누락된 키가 선택 사항이 되는 단일 요소 인터페이스로 병합합니다. 여부를 의도적으로 결정합니다null수단key?: T또는key: T | null- 그 선택은 API 가 부재 필드를 생략하는지 아니면 null 로 보내는지에 따라 달라집니다. 추론은 제공하는 샘플만 반영하므로 여러 레코드가 있는 대표 페이로드를 사용하고 출력을 완료된 계약이 아닌 검토된 첫 번째 초안으로 처리합니다.
왜 JSON에서 TypeScript 유형을 작성하는 대신 생성합니까?
정직한 대답은 손으로 쓴 유형이 드리프트 및 생성 된 유형 don & # 39;t. 백엔드가 필드를 추가하면 손으로 쓴 인터페이스가 자동으로 잘못 유지; 응답의 추가 속성이 does & # 39;t 가 언급 한 유형에는 보이지 않기 때문에 오류가 없습니다. 백엔드가 변경되면 id 숫자에서 문자열에 이르기까지 인터페이스는 계속 주장하고's 숫자와 TypeScript는 추가되는 대신 연결될 때까지 계속 동의합니다.
There's 는 또한 평범한 지루한 인수이다. 전형적인 REST 응답은 네 개의 중첩 레벨에 걸쳐 서른 개의 키를 갖는다. 손으로 그것을 전사하는 것은 순수한 기계적 작업의 십분이 소요되며,인간이 수행하는 기계적 작업은 결함 비율을 가지고있다. 당신은 키 이름을 오타할 것이다. 당신은 하나의 필드를 놓칠 것이다 that's 문자열의 배열이 아닌 객체의 배열. 생성기는 그렇지 않을 것이다.
하지만 가장 강력한 이유는 세대가 형태를 만든다는 것입니다 보이는. 변환기에 응답을 붙여 넣으면 즉시 you'd 가 원시 JSON 을 읽는 것을 얼버무린 것을 볼 수 있습니다: 그 metadata 는 실제로 깊이 중첩된 객체, 그 tags 는 때때로 비어 있습니다, 그 페이지가 매겨진 목록에있는 키의 절반은 일부 레코드에서 누락. 생성 된 인터페이스는 data's 실제 구조의 요약이며, 그것을 읽는 것은 종종 당신이 did't 쓰기 엔드 포인트를 이해하는 가장 빠른 방법입니다. I've는 문서가 거짓말이었다 API에 문서화 단계로 두 번 이상 사용.
이것이 다른 데이터 도구와 함께 맞는 경우: if you're inspecting the payload not like typing it, the JSON 포맷터 는 더 나은 첫 번째 중지, 그리고 만약 you're 두 응답을 비교 하는 버전 간에 변경 된 것을 확인 하려면, the JSON 차이점 직접적으로 대답합니다.
JSON의 유형 추론은 실제로 어떻게 작동합니까?
JSON에는 6가지 값 유형이 있습니다 RFC 8259: 개체, 배열, 문자열, 숫자, true/false, 그리고 null. TypeScript's 원시형은 그 중 네 가지에 거의 직접적으로 매핑됩니다. 흥미로운 작업은 전적으로 나머지 두 가지에 있습니다.
원시인은 사소한 것입니다. 문자열 값이 암시합니다 string. 숫자가 암시합니다 number- JSON에는 하나의 숫자 유형이 있으므로 there's 데이터에는 여부를 알려주는 정보가 없습니다 1 는 정수 또는 float 이고,TypeScript 는 does't 는 어쨌든 구별합니다. true 또는 false 함축하다 boolean. 이 부분은 애매모호함이 없다.
객체는 인터페이스가 됩니다. 모든 객체 값은 명명된 인터페이스가 되며,아래에 나타난 키는 PascalCase 로 변환된 이름을 공급합니다. 키 owner 생산합니다 interface Owner. 중첩은 반복됩니다: 객체 내부의 객체는 첫 번째에서 참조되는 두 번째 인터페이스를 생성합니다. 이것은 소리보다 더 중요합니다. 대안 - 익명으로 모든 중첩 된 모양을 인라인 - 읽을 수없는 단일 선언을 생성하고 가져올 수있는 것을 제공하지 않습니다:
// Inlined: technically correct, practically useless
interface Project {
owner: { id: number; email: string; twoFactor: boolean }
}
// Extracted: you can import and reference Owner on its own
interface Project {
owner: Owner
}
interface Owner {
id: number
email: string
twoFactor: boolean
}
한 번 Owner 이름으로 존재하며, 소유자만 취하는 함수를 입력할 수 있습니다 (owner: Owner) => void. 인라인으로 된 버전으로 you'd 는 쓰고 있습니다 Project['owner'] 작동하지만 읽기가 좋지 않은 모든 곳.
배열은 실제 결정이 이루어지는 곳입니다. An array's type 은 그 요소 타입들의 합집합이므로 [1, 2, 3] 제공합니다 number[] 그리고 [1, "a"] 제공합니다 (number | string)[]. 두 번째 괄호를 참고하세요. 괄호가 없으면 됩니다 number | string[] 완전히 다른 것(숫자)을 의미합니다 또는 문자열 배열)과 이를 잊어버린 생성기는 컴파일되지만 잘못된 것을 설명하는 코드를 방출합니다.
빈 배열은 정직한 막다른 골목입니다. "tags": [] 키가 존재하고 배열을 보유하고 있음을 알려줍니다; 그것은 당신에게 그것에 들어가는 것에 대해 아무것도 알려주지 않습니다. 올바른 출력은 unknown[]그리고 당신은 완성 된 대답보다는 추측을 거부하는 생성기로 그것을 읽어야합니다. 문서에서 자신을 채우거나 배열이 isn't 비어있는 샘플을 찾으십시오.
객체 배열이 통합되지 않고 병합되는 이유는 무엇입니까?
이것은 하나의 you'd 사용에서 발전기 you'd를 5 분 후에 포기하는 분리하는 단 하나 결정이다.
레코드가 aren't 완벽하게 균일한 페이지가 매겨진 응답을 고려하십시오. 즉, 모든 실제 페이지가 매겨진 응답은 다음과 같습니다:
{
"rows": [
{ "id": 1, "name": "Ada", "nickname": "The Countess" },
{ "id": 2, "name": "Grace" }
]
}
각 요소를 독립적으로 처리하면 두 인터페이스의 결합을 얻을 수 있습니다: rows: (Row1 | Row2)[]. 이것은 기술적으로 샘플의 가장 정확한 판독, 그리고 그것은 쓸모없는. 에 대한 모든 액세스 row.nickname 이제 좁혀야 합니다. 왜냐하면 TypeScript can't 는 여러분이 가지고 있는 유니온의 멤버를 알기 때문입니다. 그것을 몇 개의 선택적 필드를 가진 오십 레코드 응답으로 확장하면 여러분은 거의 동일한 인터페이스 수십 개의 유니온을 원하지 않습니다.
유용한 독서는 이 두 객체가 하나의 엔터티의 두 인스턴스라는 것입니다 nickname 는 분야 Grace doesn't have:
interface Row {
id: number
name: string
nickname?: string
}
interface T {
rows: Row[]
}
That's a merge: 모든 요소에서 보이는 모든 키를 수집하고,그 중 어느 것에도 없는 경우 it's 인 경우 키 옵션을 표시합니다. 데이터가 실제로 생성되는 방식 - 하나의 데이터베이스 테이블,하나의 직렬화기,일부 nullable 열 - 과 일치하며,의식 없이 사용할 수 있는 유형을 생성합니다. 배열 요소 이름도 특이화되어 있습니다 releases 수확하다 Release 보다는 Releases, 왜냐하면 releases: Releases[] 때에도 버그처럼 읽는다't.
트레이드오프는 실제이며 명백하게 언급할 가치가 있습니다: 병합은 배열이 동질적이라고 가정합니다. 만약 당신이 진정으로 이질적인 배열을 가지고 있다면 - a 에 의해 차별되는 다른 모양을 가진 이벤트들의 피드입니다 type 필드 - 병합은 거의 모든 것이 선택 사항인 하나의 인터페이스로 뚜렷한 변형을 평평하게 만듭니다. That's 잘못된 모델,it's 생성된 출력을 시작점으로 가져와 적절한 차별화된 합집합을 손으로 작성해야 하는 경우입니다. 생성기 don't know your domain. This one merges objects and uniones everything else,which is right most of time and wrong in a way you can spot immediate.
null은 선택적 키가 되어야 할까요, 아니면 조합원이 되어야 할까요?
두 규칙 모두 방어 가능하고 차이점이 있으므로 도구의 기본값을 수락하지 않고 의도적으로 결정하십시오.
주어진 { "retiredAt": null }, 두 가지 판독값이 있습니다:
interface A { retiredAt?: string } // the field may be absent
interface B { retiredAt: string | null } // the field is present and may be null
그들은 상호 교환 할 수 없습니다. 에서 A, retiredAt 이다 string | undefined 그리고 그 열쇠가 객체에 전혀 존재하지 않을 수도 있습니다. In B는, 열쇠는 항상 존재하고, 그것의 가치는 일지도 모릅니다 null. 아래에 strictNullChecks- 어느 것 타입스크립트 핸드북 추천하고 꼭 해야 할 사항 - 둘 다 부재 사건을 처리하도록 강요하지만 서로 다른 수표를 강요하고 다르게 직렬화합니다. JSON.stringify 생략하다 undefined 속성을 완전히 방출합니다 null 널의 경우 선택이 와이어로 다시 전파됩니다.
정답은 API's 실제 동작에 따라 달라지며, 이는 어떤 생성자도 하나의 샘플에서 볼 수 없습니다:
| 귀하의 API's 동작 | 올바른 모델 | 왜 |
|---|---|---|
| there's 값이 없을 때 키를 생략합니다 | key?: T |
열쇠는 진짜로 isn't 거기; 선택 정확합니다 |
항상 키를 보내, null 비어있을 때 |
key: T | null |
열쇠는 항상 존재합니다; ? 부재를 잘못 허용할 것입니다 |
| 일관성이 없음 - 때로는 생략되고 때로는 null입니다 | key?: T | null |
두 경우 모두 실제; 둘 다 모델링 |
보낸다 null 오류 응답에만 해당됩니다 |
둘 다 - 오류를 별도로 모델링하지 않습니다 | 널러블 필드는 응답 모양의 합집합을 숨기고 있습니다 |
그 마지막 행은 일시 중지할 가치가 있는 행입니다. 실패의 경우에만 null 로 가는 필드는 끝점이 하나의 모양을 입고 두 개의 다른 것을 반환한다는 신호이며,픽스는 nullable 속성이 아닌 상태 필드의 차별화된 합집합입니다. 유형 생성은 이 패턴을 표면화합니다; it doesn't 는 그것을 해결합니다.
변환기의 기본값은 다음과 같습니다 key?: T 왜냐하면 omitted-when-absent 는 JSON APIs I've 와 함께 작업한 더 일반적인 규칙이고,위에 설명된 배열 병합으로 더 잘 구성되기 때문입니다 (일부 레코드에서 누락된 키와 일부 레코드에서 that's null 이 같은 방식으로 모델링되는 키). 옵션을 끄고 null 대신 유니온에 머물러 있습니다. 둘 다 트릭이 아닙니다; API 가 실제로 수행하는 것을 선택하십시오.
aren't 유효한 TypeScript 식별자인 키는 어떻습니까?
JSON 객체 키는 임의의 문자열입니다. TypeScript 속성 이름을 베어에 넣습니다 key: T 위치는 아닙니다 - 그들은 유효한 식별자이어야 합니다. 그래서 "content-type", "2fa", "user.name", 그리고 "" 인터페이스에서 인용되지 않은 상태로 작성할 수 없는 모든 법적 JSON 키입니다.
수정 사항은 인용 중이며 it's는 해결 방법이 아닙니다. 인용된 속성 이름은 일반 TypeScript입니다:
interface Headers {
"content-type": string
"2fa": boolean
class: string
}
해당 속성은 괄호 표기법(bracket notation)을 사용하여 액세스됩니다headers["content-type"]약간 더 장황하지만 완전히 형식에 안전한 )입니다. 참고하세요 class doesn't 는 인용을 필요로 합니다: 예약된 낱말은 것과 같이 완벽하게 합법적입니다 속성 이름비록 they're 가 식별자로서 불법임에도 불구하고. 제한은 TypeScript 가 식별자를 기대하는 경우에만 적용됩니다 - 이것이 동일한 단어가 인터페이스가 될 때 처리가 필요한 이유입니다 이름.
그러한 키들로부터 파생된 인터페이스 이름들은 인용하는 것보다 더 많은 작업이 필요하다. 2fa 파스칼케이스 2fa는,어떤 can't 식별자를 시작해서 접두사를 얻습니다. 두 개의 다른 중첩된 객체 둘 다 키 이름 아래에 있습니다 owner 둘 다 그러고 싶을 것입니다 Owner, 두 번째는 됩니다 Owner2. 이들은 unglamorous 세부사항이고,they're 정확하게 생성한 산출이 컴파일하거나 그것 전에 손 수선의 십오분을 필요로 하는 것을 결정하는 세부사항입니다. 내가 변환기를 붙드는 시험은 간단합니다: 유효한 무엇이든을 풀칠하고,산출은 밑에 컴파일해야 합니다 strict 편집이 없습니다.
인터페이스 또는 유형 별칭?
생성기는 둘 중 하나를 방출합니다. 실제적인 차이는 좁지만 실제이며,코드베이스는 아마도 이미 lint config 에 인코딩된 의견을 가지고 있을 것입니다.
interface User {} 선언 병합 지원 - 동일한 인터페이스 이름을 두 번 선언하고 TypeScript 가 결합합니다. That's essential for augmenting types from library you don't control,and a footgun everywhere else,since two unrelated declarations of the same name 은 오류 대신 묵묵히 병합되기 때문에 인터페이스도 지원합니다 extends제약 조건이 실패할 때 교차 유형보다 약간 더 나은 오류 메시지를 생성합니다.
type User = {} 보통 기능인 can't 병합과 it's 필수 istn't 가 객체 모양인 모든 것에 대해: unions,tuples, mapped type,조건부 타입. isn't 가 JSON 객체인 루트 - 숫자의 배열,맨손 문자열 - 는 별칭으로만 표현될 수 있습니다 type Nums = number[] 설정에 관계없이 얻을 수 있는 것입니다.
내가 기대는 생성된 API 타입의 경우 interface는,대부분 오류 메시지가 약간 더 낫기 때문에 그리고 모든 이름이 하나의 생성된 파일에 존재할 때 병합 위험이 이론적이기 때문입니다. 그러나 이것은 동전 던지기에 가깝고,주변 코드와의 일관성이 장점보다 더 중요합니다. ESLint config 가 가지고 있다면 @typescript-eslint/consistent-type-definitions 어느 쪽이든 설정하고 일치시킨 후 생각을 중단하십시오.
이것이 JSON Schema to TypeScript 와 어떻게 다른가요?
이것들은 진정으로 다른 문제를 해결하고 it's 정확할 가치가 있습니다. 왜냐하면 "JSON에서 TypeScript"까지; 그리고 "JSON 스키마에서 TypeScript"까지; 한 단어 떨어져 있고 자주 혼동됩니다.
JSON to TypeScript는 예제에서 추론한 것입니다. Input: a value. generator 는 거기서 what's 를 관찰하고 generalises 한다. 필드가 필요한지,문자열이 enum 에 구속되는지,숫자가 최소값을 갖는지,붙여넣은 하나의 샘플이 대표성을 내포하는 모든 것을 가진,단일 관측값으로부터의 It's 귀납법.
JSON 스키마를 TypeScript로 변환하는 것은 선언에서 번역된 것입니다. 입력: a JSON 스키마 이미 유형을 명시한 문서입니다 required 배열,열거, 형식,제약 조건. 생성기 isn't 추측 - it's 기존 계약을 TypeScript 구문으로 음역. required 비선택적 속성에 대한 맵; an enum 문자열 리터럴 결합에 대한 맵; oneOf 유니온 유형으로 매핑합니다.
규칙은 다음과 같습니다: 스키마가 존재한다면, 사용하라. JSON 스키마, OpenAPI 사양, a .proto 파일 또는 GraphQL 스키마는 샘플링된 응답이 결코 존재하지 않는 방식으로 권위가 있습니다. 문서화되지 않은 내부 엔드포인트, 문서가 오래된 타사 API, 유기적으로 성장한 구성 파일 형식, 고정 장치 you're 쓰기 테스트 등 스키마가 없을 때 추론이 도달합니다. 공정하게 말하면 우리 중 누구라도 실제로 다루는 JSON의 상당 부분을 설명합니다.
There's 언급할 만한 중간 경로: use inference to 부트스트랩을,그리고 손으로 유지. 형상과 필드 이름을 오른쪽 얻기 위해 실제 응답에서 인터페이스를 생성 한 다음 편집 - 조여 a string 허용된 값을 알고 있는 문자 그대로의 결합으로 다음을 수정합니다 unknown[] 샘플은 비어 남아, 적절한 차별 유니온으로 병합 된 인터페이스를 분할. 생성기는 기계적 90% 를 수행하고 당신은 구조적으로 가질 수없는 도메인 지식을 적용합니다.
추론은 어디에서 잘못됩니까?
짧고 정직한 목록. 이들 모두는 접근 방식의 한계이지 특정 도구의 버그가 아니며,이를 아는 것이 생성 된 유형을 잘 사용하는 것과 그들에 의해 화상을 입는 것의 차이입니다.
단일 샘플은 유형을 과소 결정합니다. A 필드 that's number 귀하의 샘플에 있을 수 있습니다 null 기록의 5%에서. 당신이 풀칠한 모든 3 개의 기록에 존재하는 분야 that's 는 가득 차있는 데이터세트를 통해 선택적일지도 모릅니다. 추론은 그것이 본 무슨을 보고합니다. 더 많은 기록을 풀칠하십시오 - 이상적으로 1 개의 손으로 골라낸 목표 보다는 결과의 진짜 페이지 - 그리고 optionals 는 의미심장하게 더 정확한 얻습니다.
문자열은 실제 유형을 숨깁니다. ISO 타임스탬프, UUID, URL, 이메일 주소는 모두 그냥 string JSON 파서에. "2026-07-16T09:00:00Z" 는 의미상 날짜입니다; 데이터에는 아무 것도 그렇게 나와 있지 않습니다. If your codebase has a branded ISODateString 유형, you're 손으로 대입.
숫자는 정밀도 구분을 잃습니다. JSON's 단일 숫자 유형은 서버에 64 비트 정수 that's 가 자바 스크립트 번호로 도착하고 생성기가 그것을보기 전에 이미 정밀도를 잃어 버렸을 수있는 ID 를 의미합니다 - Number.MAX_SAFE_INTEGER 는 약 9×10¹5 이고,트위터는 이것을 어렵게 배운 것으로 유명합니다. API 가 큰 정수를 문자열로 보낸다면 that's why,and the generated string 는 맞다.
문자적 값은 일반적인 유형과 같습니다. "status": "active" 추론하다 string, 아니다 "active" | "archived" | "pending". 좁은 유형이 더 유용하며 어떤 샘플도 이를 증명할 수 없습니다. 이것은 생성된 출력에 대해 제가 직접 편집하는 가장 일반적인 것입니다.
빈 컨테이너는 아무 말도 하지 않는다. [] 제공합니다 unknown[] 그리고 {} 빈 인터페이스를 제공합니다. 둘 다 정직한 발전기입니다.
이 중 어느 것도 추론을 안전하지 않게 만들지 않습니다. 즉, 추론을 안전하지 않게 만듭니다 초안. 작동하는 워크플로는: 생성하고,산출을 주의깊게 읽고,표본 couldn't 가 말하고,저지한다는 것을 당신이 알고 있는 4 개 5 개의 것을 고치십시오. That's 는 실제적인 대안인 손으로 30 개의 열쇠를 필사하기 보다는 아직도 더 빠르고 더 정확한 크기의 순서입니다.
내 JSON이 아무데나 업로드되나요?
아니요, 이것은 질문이 배지가 아닌 실제 답변을 받을 자격이 있는 도구 범주입니다.
JSON you'd 에 있는 what's 를 유형 생성기에 붙여넣기 생각해 보세요. It's API 응답으로,이는 베어러 토큰,세션 식별자,고객 이메일,내부 사용자 ID,가격 계층,웹훅 비밀을 그럴듯하게 포함하고 있음을 의미합니다. That's not hypothetical - it's the modal case,because the whole point is that you grabbed a 진짜 유형에 대한 대응.
모든 서버 측 변환기는 반드시 그 페이로드를 수신합니다. 그것은 그것을 기록하지 않을 수 있습니다,그리고 그것은 아마도 does't,하지만 you're 확장 신뢰 당신은 don't 를 확장해야하고,데이터에 따라 당신은 전혀 네트워크를 만지고 비즈니스가없는 작업에 대한 규정 준수 문제를 만들 수 있습니다.
유형 추론은 구문 분석된 값에 대한 순수한 계산입니다. 네트워크,계정, 저장소가 필요하지 않습니다. Toolz.dev 의 변환기는 탭에서 실행되는 종속성이 없는 TypeScript 의 수백 줄입니다; 페이로드는 브라우저's 메모리의 JavaScript 문자열이며 그대로 유지됩니다. you'd 가 그러한 주장을 확인하는 방식으로 이를 확인할 수 있습니다. - 네트워크 탭을 열고 생성 또는 Wi-Fi 를 끄고 계속 작동하는 것을 지켜보세요. 이것은 사이트의 모든 도구 뒤에 있는 동일한 원리이며 I've 는 왜 더 광범위하게 중요한지에 대해 썼습니다 브라우저 기반 도구가 민감한 데이터에 대해 서버 측 도구를 능가하는 이유.
작업된 예
Here's 는 위 각 규칙을 운동하기 위하여 고의로 건설하는 공구가 발송하는 견본입니다:
{
"id": 4821,
"name": "Toolz",
"isPublic": true,
"retiredAt": null,
"owner": {
"id": 12,
"email": "[email protected]",
"twoFactor": false
},
"tags": ["developer", "privacy", "browser"],
"releases": [
{ "version": "1.0.0", "downloads": 1420, "notes": "First cut" },
{ "version": "1.1.0", "downloads": 3310 }
]
}
라는 이름의 뿌리와 Project, 그것은 다음을 생성합니다:
export interface Project {
id: number
name: string
isPublic: boolean
retiredAt?: null
owner: Owner
tags: string[]
releases: Release[]
}
export interface Owner {
id: number
email: string
twoFactor: boolean
}
export interface Release {
version: string
downloads: number
notes?: string
}
무슨 일이 있었는지 읽어보세요. owner 자체 인터페이스로 추출되어 이름으로 참조되었습니다. tags 에 무너졌습니다 string[] 모든 요소가 문자열이었기 때문입니다. releases 두 멤버를 하나로 합쳤습니다 Release- 단수화 - 그리고 notes 두 번째 릴리스 did't가 하나를 가지고 있기 때문에 선택 사항이 되었습니다. retiredAt 관찰된 유일한 값이 null이므로 선택 사항이 되었습니다.
그리고 지금 당신이 & # 39;d 수정 내용을 읽으십시오. retiredAt?: null 는 생성기's 정직한 보고서는 null이 아닌 값을 본 적이 없으며 it's 유형으로 쓸모가 없습니다 - you'd 로 변경합니다 retiredAt?: string 당신이 그것을 알고 있기 때문에's 는 존재할 때 타임스탬프. 그 단일 편집은 전체 교훈입니다: 생성기는 하나의 붙여넣기에서 바로 일곱 키 구조,중첩, 배열 병합 및 선택성을 얻었고,필드가 무엇을 의미하는지 알아야 하는 하나의 결정을 남겼습니다.
자주 묻는 질문
JSON을 TypeScript 인터페이스로 어떻게 변환합니까?
JSON 을 변환기에 붙여넣고 루트 유형 이름을 리소스 호출이 무엇이든 간에 설정하고 생성 을 누릅니다. 모든 키의 유형을 추론하고 중첩된 개체를 자체 명명된 인터페이스로 끌어오고 개체 배열을 단일 요소 유형으로 병합하고 코드를 출력하여 a 로 바로 복사할 수 있습니다 .ts 파일. There's 가입 및 업로드 없음 - 추론은 브라우저에서 실행됩니다.
객체 배열은 어떻게 됩니까?
They're 는 단일 요소를 설명하는 하나의 인터페이스로 병합되었으며 속성은 배열로 입력됩니다. 일부 배열 멤버에는 표시되지만 다른 배열 멤버에는 표시되지 않는 모든 키는 선택 사항이 됩니다. 이는 실제 페이지가 매겨진 데이터가 작동하는 방식과 일치하며 레코드는 하나의 테이블에서 나오고 일부 열은 nullable 이 됩니다. 잘못 처리하는 한 가지 경우는 서로 다른 이벤트 유형의 진정으로 이질적인 배열이므로 식별된 조합으로 직접 변환해야 합니다.
null은 선택적 키가 되어야 할까요, 아니면 null과의 결합이 되어야 할까요?
API 가 부재 필드를 생략하는지 아니면 null 로 보내는지에 따라 다릅니다. 생략하면 key?: T 는 정확하다. 만약 키가 항상 존재하고 가끔 null 이라면 key: T | null 정확하고 사용됩니다 ? 키가 누락되도록 잘못 허용합니다. 변환기는 기본적으로 선택 사항으로 설정되어 전환할 수 있습니다. 왜냐하면 두 직렬화가 다르기 때문입니다 JSON.stringify 정의되지 않은 속성을 삭제하지만 null 속성을 내보냅니다.
단일 JSON 샘플에서 정확한 유형을 추론할 수 있습니까?
정확한 종류를 추론해내는 것이다 그 샘플에which isn't the same thing. 당신의 한 레코드에 있는 어떤 숫자가 다른 레코드에서는 null 일지도 모르는 필드 that's a number in your one record might be null; 당신이 붙여넣은 세 레코드 모두에 존재하는 필드는 전체 데이터셋에 걸쳐 선택사항일지도 모른다. 한 개의 손으로 고른 객체가 아닌 여러 개의 레코드가 있는 대표 페이로드를 사용하고,출력을 완성된 계약이 아닌 검토된 초안으로 처리한다.
What's JSON to TypeScript 와 JSON 스키마를 TypeScript 로의 차이는 무엇입니까?
이 도구는 예제 값에서 타입을 추론합니다; JSON 스키마를 TypeScript 로 변환하면 이미 타입,필수 필드 및 열거형을 선언하는 형식 스키마를 번역합니다. 스키마는 권위 있고 추론은 추측이므로 JSON 스키마,OpenAPI 사양 또는 GraphQL 스키마가 있는 경우 추론은 스키마가 존재하지 않고 응답 본문만 있는 매우 일반적인 경우에 대한 것입니다.
어떻게 aren't 유효한 식별자 키를 처리합니까?
대시, 점, 공백 또는 선행 숫자가 있는 키가 출력에 인용됩니다 "content-type" 된다 "content-type": string. That's 유효한 TypeScript,괄호 표기법으로 접근. 같은 예약된 단어 class don't 는 속성 이름으로 인용할 필요가 있습니다. 그런 키에서 파생된 인터페이스 이름은 PascalCased 이고,만약 they'd 가 숫자로 시작하고,충돌하는 이름은 숫자 접미사를 얻으므로 출력은 항상 컴파일됩니다.
인터페이스를 생성해야 합니까, 아니면 별칭을 입력해야 합니까?
코드베이스가 이미 수행하는 모든 작업을 일치시킵니다 - 대부분 일관성 질문입니다. 인터페이스는 선언 병합을 지원합니다 extends그리고,약간 더 명확한 오류 메시지를 준다. type aliases can't merge,이는 보통 바람직하며,isn't an object shape 인 어떤 것에 대해서도 요구된다. a root that's an array or a primitive is emitted as a alias either way,since there's no object to declare an interface for.
내 json이 서버에 업로드되었습니까?
아니요. 전체 추론 엔진은 브라우저에서 JavaScript 로 실행되며 네트워크 호출,로깅 및 저장소가 없습니다. 이것은 대부분의 도구보다 여기에서 더 중요합니다. JSON you'd 를 유형 생성기에 붙여 넣는 것은 일반적으로 토큰,고객 기록 또는 내부 ID 를 생성하는 동안 네트워크 탭을 열거나 인터넷에서 연결을 끊습니다. - 계속 작동합니다.
관련 도구: JSON 포맷터 먼저 페이로드를 검사하기 위해 JSON에서 YAML로 그리고 JSON에서 XML로 형식 변환의 경우 및 JSON 차이점 두 응답 사이에서 무엇이 바뀌었는지 알아내기 위해. 추가 읽기: JSON 도구에 대한 궁극적 인 가이드 그리고 the developer's 코딩 도구 가이드.



