TypeScript ve React Hooks (I) ile Daha İyi Bileşenler Nasıl Oluşturulur


Nelio, Ruth ve Toni'deki ortaklarımla çalışmanın en sevdiğim yanlarından biri, hangi projeler üzerinde çalışacağımızı ve bunları nasıl uygulayacağımızı seçme imkanı. Ayrıca, fırsat buldukça yeni teknolojileri öğrenmekten ve denemekten keyif alıyoruz. Bu nedenle, bir şeye her başladığımızda, bunu şimdiye kadar öğrendiklerimizi bütünleştirmek ve böylece işleri daha iyi yapmak için bir fırsat olarak görmemiz şaşırtıcı olmamalı.

Bugünün gönderisi, size türler hakkında konuşmak istiyorum ve özellikle TypeScript'te iyi bir tür tanımının eklentilerimizin geliştirilmesine nasıl rehberlik edebileceği ve daha sağlam, güvenilir ve bakımı yapılabilir bir yazılım oluşturmamıza izin verebileceği hakkında. Ayrıca, Ruth'un birkaç gün önce size bahsettiği Nelio Popups adlı gerçek bir örnekle bunu açıklayacağım. Umarım beğenirsiniz ve bizim gibi sonraki projelerinizde denemek istersiniz.

TypeScript'e Genel Bakış

TypeScript, JavaScript'i türlerle genişleten bir programlama dilidir. Amacı basittir: JavaScript kodumuzu güçlü bir şekilde yazmak, çalışma zamanı hatalarını önlememize yardımcı olacak (derleyici bunları derleme zamanında algılayacaktır) ve daha iyi, daha güvenilir yazılımlara yol açacaktır.

Örneğin, bir kullanıcı hakkında bilgi içeren bir nesnemiz olduğunu hayal edin: ad, şifre vb.

 const u = { name: 'David', password: 'some-nice-password', };

Ardından, bir kullanıcının parolasının “güvenli” olup olmadığını kontrol eden bir fonksiyonumuz olduğunu varsayalım (yani 8 veya daha fazla karakter içeriyor):

 function hasSafePassword( user ) { return 8 <= user.pasword.length; } hasSafePassword( u ); // ERROR!

Görünüşe göre 10 satırdan daha az kodda, ilk bakışta yakalanması zor olan bir hatamız var. Açık hale getirmek için kodu çalıştırmalıyız:

 Uncaught TypeError: user.pasword is undefined hasSafePassword

İşte yanlış giden şey: kullanıcımız bir parola özniteliğine sahip değil… çünkü onu yanlış pasword ! Aslında iki s ile password

Aynı kodu TypeScript kullanarak uygulamış olsaydık ve bir User nesnesi için aşağıdaki gibi bir tür tanımı sağlasaydık:

 type User = { readonly name: string; readonly password: string; }; // A const u: User = { name: 'David', password: 'some-nice-password', }; // B function hasSafePassword( user: User ) { return 8 <= user.pasword.length; } // C hasSafePassword( u );

derleyici hatayı yarasadan hemen yakalayabilirdi:

 Property 'pasword' does not exist on type 'Person'. Did you mean 'password'?

Oldukça basit bir örnek, dürüst olalım, ikimiz de seni tanıyoruz ve birkaç kez karşılaştık… ve sağlam bir tip sistemle hızla ele alınabilir.

Birlik Türleri

TypeScript ile ilgili en havalı şeylerden biri, herhangi bir değişken veya parametrenin birden fazla türe sahip olabilmesidir. Örneğin, önceki örnekte, u sabitinin hasSafePassword işlevindeki user parametresinin yanı sıra tam olarak User türünde olması gerektiğini gördük. Şimdi, farklı türlere sahip olmak için bir değişkene veya parametreye ihtiyaç duyduğumuz durumlar var. Bunun paradigmatik bir örneği bir Redux redüktörüdür .

Bir önceki gönderide tartıştığımız gibi, bir Redux mağazası, uygulamamızın durumunu takip etmemizi sağlar. Güncellemek için, iki argüman (uygulamamızın mevcut durumu ve onu güncellemek için gerekli bilgileri içeren bir eylem) alan ve yeni bir durum üreten bir reducer yöntemimiz var:

 function reducer( state: State, action: Action ): State

Mantıksal olarak, bir reducer aldığı eylemlerin tümü birbirinden farklıdır. Örneğin, bir YAPILACAKLAR listesi uyguluyorsak, aşağıdaki gibi eylemlerimiz olabilir:

  • Görev oluştur : bir kimlik ve görev tanımı verildiğinde, onu uygulama durumuna ekleyin.
  • Bir görevi sil : Bir görevin kimliği verildiğinde, onu uygulama durumundan kaldırın.
  • Bir görevin durumunu değiştirme : bir görevin kimliği verildiğinde, beklemedeyse tamamlandı olarak işaretleyin (ve tam tersi).

TypeScript'te:

 type NewTask = { readonly type: 'NEW_TASK'; readonly id: string; readonly task: string; } type RemoveTask = { readonly type: 'REMOVE_TASK'; readonly id: string; } type ToggleTaskStatus = { readonly type: 'TOGGLE_TASK_STATUS'; readonly id: string; }

Gördüğünüz gibi, böyle küçük bir uygulamanın eylemleri ya NewTask , RemoveTask ya da ToggleTaskStatus . TypeScript'in boru sembolünü kullanarak temsil ettiği "tür birliği" olarak bilinen şey budur:

 type Action = | NewTask | RemoveTask | ToggleTaskStatus;

Tip Muhafızlar

Kod çalışırken, YAPILACAKLAR listesi örneğimizdeki bir action yalnızca belirli bir türü olacaktır. Tanımlarına yakından bakarsanız, NewTask , RemoveTask ve ToggleTaskStatus hepsinin bir type özelliğine (bu arada Redux mağazalarında standart bir kuraldır) ve bir id özelliğine sahip olduğunu fark edeceksiniz. Ayrıca NewTask biraz farklı olduğunu fark edeceksiniz: ayrıca bir task özelliği de var.

Bir action kullanmadan önce tam türünü bilmemiz gerekir. Bunu yapmak için "tip korumaları" denen bir şey kullanıyoruz. Bir tür koruyucu, belirli bir değişkenin belirli bir türü veya başka bir türü olup olmadığını doğrulayan basit bir işlevdir. Eylemler söz konusu olduğunda, bu kontrol çok basittir, çünkü belirli eylem türünü bilmek için tek yapmamız gereken onun type niteliğine bakmaktır, ha:

 function reducer( state: State, action: Action ): State { switch ( action.type ) { case 'NEW_TASK': return { ...state, [ action.id ]: { completed: false, task: action.task, } }; ... } }

Bu nedenle, aldığımız action bağlı olarak bir şeyi veya diğerini yapmak için bir switch bloğu kullanabiliriz. type NEW_TASK olduğunda, bize bir NewTask eylemi verildiğinden emin oluruz ve bu nedenle action , task niteliğini içerir.

Bu tür birliğine "ayrımcı türler birliği" denir, çünkü adından da anlaşılacağı gibi, bir tür birliğidir ve hepsi ortak bir özniteliği paylaşır (bu durumda, type ) ve bir türü diğerlerinden ayırt etmemize izin verir. diğeri.

Ancak tüm tür birliklerinde bir ayrımcı yoktur. İki farklı türün, onları ayırt edecek belirli bir niteliği olmaması tamamen mümkündür:

 type Element = Post | Task; type Post = { readonly id: number; readonly title: string; } type Task = { readonly id: number | string; readonly task: string; readonly completed: boolean; }

Dolayısıyla şu soru ortaya çıkıyor: Belirli bir Element aslında bir Post mi yoksa Task mi olduğunu nasıl anlayabiliriz? Peki, "tür yüklemleri" kullanmamız gerekiyor. Bir tür yüklemi, temel olarak, belirli bir değişkenin belirli bir türde olup olmadığını kontrol etmekten sorumlu olan bir yüklem işlevidir (yani bir boole işlevi):

 const isPost = ( el: Element ): el is Post => undefined !== ( el as Post ).title; const isTask = ( el: Element ): el is Task => undefined !== ( el as Task ).task;

isPost ve isTask , bir Element nesnesi alan ve bize Element sırasıyla bir Post mi yoksa Task mi olduğunu söyleyen iki farklı işlevdir. Bunu yapmak için, her ikisi de yalnızca Post veya Task sahip olduğu öznitelikler olduğu gerçeğinden yararlanır. Örneğin, el bir title varsa, bunun Post olduğunu biliyoruz.

Bu tür yüklemlerle daha sonra şöyle şeyler yapabiliriz:

 function stringify( el: Element ): string { return isPost( el ) ? el.title : el.task; }

öğenin bir Post olup olmadığını kontrol etmek için isPost tipi korumayı kullandığımız yer. Eğer öyleyse, title döndürürüz; değilse, TypeScript el bir Task olması gerektiğini bilir ve bu nedenle, onun niteliğine bakabiliriz task . Bu örnekle burada oynayabilir ve herhangi bir hata olmadığını görebilirsiniz.

Şimdi ne olacak?

Umarım TypeScript ile ilgili bu kısa girişi ilginç bulmuşsunuzdur. Artık bazı temel tip teorilerini daha iyi anladığınıza göre, daha iyi yazılım yazmak için bilmeniz gereken her şeyi biliyorsunuz. Gelecek hafta, sendika türlerinin ve güvenlik korumalarının nasıl daha iyi tasarımlara yol açacağını göreceğiz. Ayrıca “imkansız durumları imkansız hale getirmenin” önemini de öğreneceğiz.

Haftaya görüşürüz!

Unsplash'ta Kelly Sikkema'nın öne çıkan resmi.

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

Divi's Theme Builder ile Özel Global Başlık Nasıl Oluşturulur

Artık Tema Oluşturucu burada olduğuna göre, web sitenizi A'dan Z'ye kurmanıza yardımcı olacak yeni eğitimlere dalmak için sabırsızlanıyoruz. Buna Divi'nin yerleşik seçeneğini kullanarak özel başlıklar oluşturma da dahildir. Bu eğitimde Divi's Theme Builder'ı kullanarak global bir başlık oluşturmaya odaklanacağız. Bu sayfaya veya gönderiye farklı bir başlık atamadıysanız, web sitenizin her yerinde genel bir başlık görünecektir.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir