Menu

TypeScript Partial ve Required: Örnekler ve Deep Partial

Partial<T>, T tipinin her özelliğini isteğe bağlı yapar; bu da tam olarak bir güncelleme ya da patch nesnesinin tipidir. Güncelleme fonksiyonlarında Partial'ı, neden sığ olduğunu, bir DeepPartial nasıl yazılacağını, açık undefined tuzağını ve tersi olan Required<T> tipini öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Partial<T>, T tipinin her özelliğini isteğe bağlı yapan yerleşik bir utility type'tır. Bir güncelleme ya da patch için doğal tiptir: çağıran taraf yalnızca değişen alanları gönderir.

Partial<User> tipi { id?: number; name?: string; email?: string } olur. Derleyici geçirdiğiniz alanları yine kontrol eder: { nmae: "x" } ya da { name: 42 } bir hatadır; Partial tipini gevşek bir object ya da any parametresinden daha iyi yapan da budur.

Partial Nasıl Tanımlanır

Partial, TypeScript'in standart kütüphanesinde tek satırlık bir mapped type'tır:

type Partial<T> = {
  [P in keyof T]?: T[P];
};

T tipinin her P anahtarı için aynı tipte isteğe bağlı bir özellik bildirir. keyof T üzerinde eşleme yaptığı için, readonly olan özelliklerde readonly korunur. Sıradan bir tip olduğu için çalışma zamanında hiçbir etkisi yoktur: changes olarak geçirilen nesne her durumda aynı nesnedir.

Bir Partial'dan Okumak T | undefined Verir

Bir Partial<T> tipinin her özelliği eksik olabilir, bu yüzden birini okumak özellik tipini ve undefined değerini verir. Derleyici eksik durumu ele almanızı ister:

{ ...defaults, ...opts }, bir Partial<Options> değerini eksiksiz bir Options değerine geri çevirmenin olağan yoludur: önce varsayılanları yayın, verilen değerlerin onları ezmesine izin verin.

Açık undefined Tuzağı

İsteğe bağlı bir özellik eksik olabilir, ama undefined değeriyle var da olabilir. Nesne spread'i bu undefined değerini gerçek değerin üzerine kopyalar ve sonuç tipi bunu göstermez:

Bu sorun, boş alanların undefined hâline geldiği bir formdan ya da query string'den bir patch oluşturulduğunda ortaya çıkar. exactOptionalPropertyTypes derleyici seçeneği (strict kapsamında değildir), name?: string | undefined yazmadığınız sürece name?: string için { name: undefined } ifadesini bir derleme hatası yapar ve sorunu kaynağında önler.

Partial Sığdır

Partial yalnızca en üst düzey özellikleri isteğe bağlı yapar. İç içe bir nesneyi geçirirseniz, o nesne eksiksiz olmalıdır:

index.ts(8,3): error TS2741: Property 'tabSize' is missing in type '{ fontSize: number; }' but required in type '{ fontSize: number; tabSize: number; }'.

editor özelliği isteğe bağlıdır, ama var olduğunda tipi değişmeden { fontSize: number; tabSize: number } olur. Ayar nesneleri, API patch'leri ve test fixture'ları için genellikle her düzeyde isteğe bağlı özellikler istersiniz. Bunun için özyinelemeli bir tip gerekir.

DeepPartial: Özyinelemeli Bir Partial

TypeScript'te yerleşik bir derin sürüm yoktur, ama birkaç satırdan ibarettir. Fonksiyonlar ve diziler olduğu gibi bırakılır, çünkü dizi elemanlarını isteğe bağlı yapmak [undefined] değerine izin verirdi:

Tip özyinelemelidir; birleştirme değildir. applySettings, editor özelliğini elle birleştirir, çünkü nesne spread'i de sığdır. lodash gibi kütüphanelerde generic bir derin birleştirme fonksiyonu (merge) vardır ve onun tiplenmesi yukarıdaki tipten daha zordur.

Required: Partial'ın Tersi

Required<T>, her özellikten ? işaretini kaldırır. -? değiştiricisiyle tanımlanmıştır; bu değiştirici her özelliğin tipinden undefined değerini de çıkarır:

Desen Partial ile aynıdır, yalnızca tersine çevrilmiştir: bir API'nin kullanıcıları gevşek bir yapılandırma geçirir, içerideki kod ise her değerin var olduğunun bilindiği bir Required sürümüyle çalışır. Spread'de yukarıdaki güncelleme fonksiyonundaki açık aynen vardır: açıkça port: undefined geçiren bir çağıran, varsayılanı undefined ile ezer ve exactOptionalPropertyTypes açık değilse derleyici bunu kabul eder. Required da Partial gibi sığdır.

Yalnızca Bazı Özellikleri İsteğe Bağlı ya da Zorunlu Yapmak

Partial ve Required her özelliğe uygulanır. Yalnızca birkaçını değiştirmek için tipi Pick ve Omit ile bölün ve yeniden birleştirin:

type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

interface Post {
  id: number;
  title: string;
  body?: string;
}

type NewPost = PartialBy<Post, "id">;      // id optional, title required, body optional
type Published = RequiredBy<Post, "body">; // body now required
TipEtkisiDerin mi?
Partial<T>her özellik isteğe bağlıhayır
Required<T>her özellik zorunlu, undefined çıkarılmışhayır
DeepPartial<T> (kendi yazdığınız)her düzeyde isteğe bağlıevet
PartialBy<T, K> (kendi yazdığınız)yalnızca K anahtarları isteğe bağlıhayır
Readonly<T>her özellik readonlyhayır

Sıkça Sorulan Sorular

TypeScript'te Partial ne işe yarar?

Partial<T>, T tipinin tüm özellikleri isteğe bağlı olarak işaretlenmiş bir tip oluşturur. interface User { name: string; email: string } için Partial<User> tipi { name?: string; email?: string } olur; böylece {}, { name: "Ada" } ve eksiksiz bir kullanıcı geçerli değerlerdir.

TypeScript'te Partial derin mi çalışır?

Hayır, Partial yalnızca en üst düzey özellikleri etkiler. Bir Partial<T> içindeki iç içe bir nesne yine eksiksiz olmalıdır. Özyinelemeli bir sürüm için, nesne tipli özelliklere kendini uygulayan bir DeepPartial<T> tipi yazın.

TypeScript'te Partial'ın tersi nedir?

Required<T>. Her özellikten ? işaretini kaldırır ve tiplerinden undefined değerini de çıkarır; böylece Required<{ port?: number }> tipi { port: number } olur. -? değiştiricisine sahip bir mapped type olarak tanımlanmıştır.

Yalnızca bazı özellikleri nasıl isteğe bağlı yaparım?

Omit, Pick ve Partial tiplerini birleştirin: type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>. PartialBy<User, "email"> her özelliği olduğu gibi bırakır, yalnızca email isteğe bağlı hâle gelir.

Bir Partial güncellemesi birleştirildikten sonra bir özellik neden undefined oluyor?

Partial<T>, bir özelliğin undefined değeriyle var olmasına izin verir ve nesne spread'i onu kopyalar: TypeScript sonucu User olarak tiplese de { ...user, ...{ name: undefined } } içinde name: undefined bulunur. Birleştirmeden önce undefined değerlerini filtreleyin ya da açık bir undefined reddedilsin diye exactOptionalPropertyTypes seçeneğini açın.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA