JSON to TypeScript Dönüştürücü
JSON örneğinden TypeScript arayüzleri üretin. İç içe yapıları çıkarır, dizi elemanlarının tiplerini birleştirir ve örnekte bulunmayan alanları isteğe bağlı işaretler.
Soldaki alana bir JSON örneği yapıştırın, tipler burada oluşacak.
Özet (TL;DR)
- Çoğu çevirici dizinin yalnızca ilk elemanına bakar; bu araç bütün elemanları birleştirir, bir elemanda olmayan alanı
?ile isteğe bağlı yapar. - Tipleri gerçekten çakışan alanlar birleşim olur:
{ "v": 1 }ve{ "v": "1" }örnekleriv: number | stringüretir. - Üretilen tip bir SÖZLEŞME değil, elinizdeki ÖRNEĞİN tarifidir; TypeScript tipleri çalışma anında hiçbir şey doğrulamaz.
- Boş dizide eleman tipi bilinemez, o yüzden varsayılan
unknown[]üretilir;anyher hatayı sessizce yutar.
İkinci kayıtta patlayan elle yazılmış tip
API yanıtına bakıp interface'i elle yazmak ilk kayıtta kolay görünür. Alanları sırayla geçirirsiniz, editör susar, iş bitmiş sayılır. Sonra listenin ikinci kaydında note alanı hiç gelmez ve response.note.trim() çağrısı çalışma anında patlar. Tip dosyası hâlâ derleniyor, çünkü orada yazan şey verinin gerçeği değil, ilk kaydın fotoğrafı.
Neden bütün elemanları birleştirmek gerekiyor
Online çeviricilerin çoğu diziyi görünce ilk elemanı alır ve gerisini atar. Örnek veride ilk kullanıcının profil fotoğrafı varsa, tip avatar: string der; fotoğrafsız kullanıcıya geldiğinizde derleyici sizi uyarmaz çünkü tip zaten yanlış bilgi veriyor. Bu araç her elemandan çıkan şekli tek tek birleştiriyor: bir tarafta olup diğerinde olmayan alan isteğe bağlı işaretleniyor, aynı alan farklı tiplerde geliyorsa birleşim üretiliyor.
// Girdi[ { "id": 1, "note": "ilk kayit", "score": 10 }, { "id": 2, "score": "10" }] // İlk elemana bakan çevirici (yanlış)interface Item { id: number; note: string; score: number } // Bu aracın çıktısıexport type RootList = Root[]; export interface Root { id: number; note?: string; // ikinci kayitta yok score: number | string; // gerçek bir tip çatışması}İç içe nesneler ayrı birer interface olarak üretiliyor, satır içine gömülmüyor. Üç kat derine inen anonim nesne edebiyatı okunmaz hale gelir ve başka bir yerden referans veremezsiniz. users gibi çoğul bir anahtar altındaki nesne User adını alır, çakışan isimler User2 gibi numaralandırılır. Kök seviyede dizi verirseniz eleman tipi ayrı bir interface, dizinin kendisi RootList gibi bir takma ad olarak çıkar; böylece hem tek kaydı hem listeyi ayrı ayrı tipleyebilirsiniz.
Üretilen tip bir sözleşme değil
Buradaki en önemli sınır şu: çıktı, verdiğiniz örneğin tarifidir. note?: string gördüğünüzde bunun anlamı "bu alan API tarafında isteğe bağlı" değil, "bu alan verdiğiniz örneğin bir kaydında yoktu". Belki alan gerçekten isteğe bağlı, belki de yalnızca örneğiniz eksik. Tersi de geçerli: örnekte her kayıtta bulunan bir alan zorunlu görünür, oysa API onu bazı durumlarda hiç göndermiyor olabilir. Bu yüzden örneği staging verisinden değil, mümkün olduğunca çeşitli gerçek kayıtlardan toplamak işe yarıyor.
Bilgi
İsteğe bağlı ile null aynı şey değil
TypeScript'te bu ikisi farklı durumları anlatır ve karıştırıldığında yanlış yerde kontrol yazarsınız. note?: string alanın hiç bulunmayabileceğini söyler, okuduğunuzda undefined gelir. note: string | null alanın her zaman bulunduğunu ama değerinin boş olabileceğini söyler. Bir veritabanı sütununun NULL olması ile API yanıtında o anahtarın hiç yer almaması farklı olaylar, JSON örneğinizde null gördüğünde bu araç birleşim üretir, anahtar hiç yoksa isteğe bağlı yapar.
| Örnekte görülen | Üretilen tip | Anlamı |
|---|---|---|
| Her kayıtta var, string | note: string | Zorunlu alan |
| Bazı kayıtlarda yok | note?: string | Anahtar bulunmayabilir |
| Değeri null olabiliyor | note: string | null | Anahtar var, değeri boş |
| Boş dizi | items: unknown[] | Eleman tipi bilinemiyor |
| Farklı tiplerde geliyor | v: number | string | Gerçek tip çatışması |
Boş diziler ve unknown tercihi
Örnekte "tags": [] görürse araç eleman tipi hakkında hiçbir şey bilemez ve varsayılan olarak unknown[] üretir. any[] yerine unknown seçilmesinin sebebi şu: any üzerinde her işlem serbesttir, yani derleyici o noktadan sonra sizi hiç uyarmaz ve hata çalışma anına kadar saklanır. unknown ise kullanmadan önce tipi daraltmanızı zorunlu kılar, yani derleyici eksik bilgiyi görünür tutar. Ayarlar bölümünden any davranışına dönebilirsiniz ama varsayılanı değiştirmeden bırakmanızı öneririm.
Sıkça Sorulan Sorular
- Üretilen tipleri doğrudan production kodunda kullanabilir miyim?
- Başlangıç noktası olarak evet, son söz olarak hayır. Çıktı elinizdeki örneği tarif eder; API dokümantasyonuna göre gözden geçirmeniz, isteğe bağlı alanların gerçekten isteğe bağlı olduğunu doğrulamanız gerekir. Ağdan gelen veriyi gerçekten garanti altına almak istiyorsanız zod benzeri bir çalışma anı doğrulayıcısı ekleyin.
- Alanım neden isteğe bağlı işaretlendi?
- Çünkü verdiğiniz dizinin en az bir elemanında o anahtar yoktu. Bu ya alanın gerçekten isteğe bağlı olduğunu ya da örneğinizin dar kaldığını gösterir. Daha fazla kayıt yapıştırdığınızda tablo netleşir.
- Tarih alanları neden string çıkıyor?
- JSON'da tarih tipi yok.
2026-07-26T10:00:00Zağ üzerinde bir stringdir ve araç onu string olarak raporlar.Datenesnesine dönüştürmek sizin işiniz; tipi elleDateyapıp dönüşümü unutursanız derleyici sizi yakalamaz, çünküJSON.parsesonucu zatenanysayılır. - Çok büyük bir örnek yapıştırabilir miyim?
- Birkaç megabaytlık örnekler sorunsuz işlenir ama gerek de yoktur. Şekil çıkarımı için kayıt çeşitliliği kayıt sayısından önemli: isteğe bağlı alanların hepsini kapsayan on beş yirmi kayıt, aynı şekilde binlerce kayıttan daha iyi sonuç verir.
- İsteğe bağlı alan mı yoksa null mı kullanmalıyım?
- Alan bazen hiç gönderilmiyorsa isteğe bağlı (
note?: string), her zaman gönderiliyor ama boş olabiliyorsa nullable (note: string | null). API tasarlıyorsanız ikisinden birini seçip tutarlı kalın; aynı yanıtta bazı alanların eksik bazılarının null olması tüketen tarafta gereksiz kontrol yükü çıkarır.