TypeScript kodunuzda Option'ı fp-ts ile kullanma
SeçenekContainer , verileri iki olası durumla depolamanıza yardımcı olanVeri Yapısıdır ( ) : değer yok (None) veya değer mevcut (Some). JavaScript'tebir Nesnede isteğe bağlı bir değeri temsil etmek için Option'ı kullanabiliriz
Örneğin, bir Kişi Nesne Türümüz ve bir Adres Nesne Türümüz olduğunu varsayalım:
type Address = {
addressLine1: string;
addressLine2?: string;
};
type Person = {
name: string;
age: number;
address?: Address;
};
const getAddressLine2 = (person: Person) => {
// To get the address line 2,
// Need to check whether the value is empty (null or undefined or "")
if (person.address && person.address.addressLine2) {
return person.address.addressLine2;
}
// Return an empty string as the default value;
return "";
};
import * as option from 'fp-ts/Option';
const getAddressLine2 = (person: Person) => {
/*
Step 1: create an Option container and wrap the data inside Option becasue address can be empty
Use the Option constructor "option.fromNullable"
*/
const addressOption = option.fromNullable(person.address);
// Extract the value of addressLine2 from addressOption ...
};
Adres Nesnesi içindeki addressLine2'ye erişmek için sezgisel olarak şöyle bir şey yapmak istiyoruz .addressOption.addressLine2
Ancak , adresin değeri Option içinde sarıldığı için bunu yapamadık , bu nedenle adresi Option'dan açmamız ve ardından addressLine2 değerine erişmemiz gerekiyor .
Ayrıca, değer boş olabileceğinden, addressLine2 de Option'a sarılmalıdır . Dolayısıyla, address öğesinin boş olmayan değerini elde edebiliyorsak , aynısını addressLine2 için options.fromNullable(address.addressLine2) kullanarak yapabiliriz .
Aşağıdaki kod parçacıkları, addressLine2 değerini elde etmek için adresin boş olmayan değerini elde etmeye yönelik iki yaklaşımı gösterir :
import * as option from 'fp-ts/Option';
const getAddressLine2 = (person: Person) => {
/*
Step 1: create an Option container and wrap the data inside Option becasue address can be empty
Use the Option constructor "option.fromNullable"
*/
const addressOption = option.fromNullable(person.address);
/*
Step 2: Extract the value of addressLine2 from addressOption
Approach 1 -
Use "option.isSome" to extract the value
*/
if (option.isSome(addressOption)) {
// The address value can be obtained by .value
const address = addressOption.value;
// Wrap the addressLine2 with Option
const addressLine2Option = option.fromNullable(address.addressLine2);
}
// Return the value of addressLine2 ...
};
import * as option from 'fp-ts/Option';
const getAddressLine2 = (person: Person) => {
/*
Step 1: create an Option container and wrap the data inside Option becasue address can be empty
Use the Option constructor "option.fromNullable"
*/
const addressOption = option.fromNullable(person.address);
/*
Step 2: Extract the value of addressLine2 from addressOption
Approach 2 -
Use "option.map" to extract the value and wrap the addressLine2 with Option
*/
const addressLine2Option = option.map((address) => option.fromNullable(address.addressLine2))(addressOption);
// Return the value of addressLine2 ...
};
.map'i kısaca açıklamak gerekirse , kapsayıcı içindeki değeri açmanıza ve verilerle bazı dönüşümler yapmanıza yardımcı olur. ( JS'de A rray ile çalışırken .map işlevine aşina görünüyor , değil mi? :))
Bekleyin… addressLine2Option türünü kontrol ederseniz , bu Option < Option < string >> şeklindedir , addressLine2 değeri bir Option ile başka bir Option içinde sarılır ! Ama bizim istediğimiz sadece< Option < string >>!
Option'daki " map " öğesinin tip imzasına ( tip imzası İşlevsel Programlamada ÇOK ÖNEMLİ ) bakarsanız , bu f: (a: A -> b: B) -> Option<a: A> -> Option< b:B>
Şu şekilde çalışır: Önce Option<a: A>' dan “a” verisini açar , “a” değerini f'ye girdi olarak verir , “a”yı “b”ye dönüştürür, ardından “b” sonucunu Seçenek ve iade et. (Not: Option<a: A> Yok ise, f işlevi tetiklenmez ve orijin değeri (Yok) döndürülür.)
Bu nedenle , daha önce < Option < string >> yerine Option < Option < string >> alırız !
Neyse ki, kolayca düzeltebiliriz! Her iki katman da Seçenek olduğundan, dış katmanı kaldırmak için .flatten kullanabiliriz :
const addressLine2Option = option.map((address) => option.fromNullable(address.addressLine2))(addressOption);
const addressLine2OptionForReal = option.flatten(addressLine2Option);
const addressLine2Option = option.chain((address) => option.fromNullable(address.addressLine2))(addressOption);
Son olarak, eğer değer boşsa, addressLine2'nin değerini default değeri olan “” ile options.getOrElse kullanarak döndürmeliyiz :
import * as option from 'fp-ts/Option';
const getAddressLine2 = (person: Person) => {
/*
Step 1: create an Option container and wrap the data inside Option becasue address can be empty
Use the Option constructor "option.fromNullable"
*/
const addressOption = option.fromNullable(person.address);
/*
Step 2: Extract the value of addressLine2 from addressOption
Approach 2 -
Use "option.chain" to extract the value and wrap the addressLine2 with Option and then flatten the result
*/
const addressLine2Option = option.chain((address: Address) => option.fromNullable(address.addressLine2))(addressOption);
/*
Last Step: Return the value of addressLine2 with the default value "" if empty
*/
const result = option.getOrElse(() => "")(addressLine2Option);
return result;
};
const personA = {
name: "A",
age: 20,
address: {
addressLine1: "hehe",
addressLine2: "haha",
}
}
// You should get "haha"
getAddressLine2(personA);
Bilginize, verileri düzene sokmak için boru ve işlev bileşimi için akış kullanırdım (Güven bana, bu son sürüm!).
import * as option from 'fp-ts/Option';
import {pipe, flow} from 'fp-ts/function';
type Address = {
addressLine1: string;
addressLine2?: string;
};
type Person = {
name: string;
age: number;
address?: Address;
};
const getAddressLine2Final = flow(
option.fromNullableK((person: Person) => person.address),
option.chain(address => option.fromNullable(address.addressLine2)),
option.getOrElse(() => '')
);
const personA = {
name: 'A',
age: 20,
address: {
addressLine1: 'hehe',
addressLine2: 'haha',
},
};
// You should get "haha"
pipe(personA, getAddressLine2Final);
Nesnede daha iç içe geçmiş isteğe bağlı özellikler olduğunu hayal edin. Örnekler için, addressLine2 türü artık bir dize değildir, ancak şu şekilde değiştirilir:
type AddressLine2 = {
country?: {
city?: string;
}
}
person.address && person.address.addressLine2 &&
person.address.addressLine2 && person.address.addressLine2.country &&
person.address.addressLine2.country.city
option.chain(addressLine2 => option.fromNullable(address.country)),
option.chain(country => option.fromNullable(country.city)),
fp-ts hakkında daha fazla bilgi .
Okuduğunuz için teşekkürler
Umarım bu makaleyi beğenir ve ondan bir şeyler kazanırsınız. Fonksiyonel Programlamayı öğrenmenin artık sizin için daha az göz korkutucu olmasını diliyorum :)
Ka Hin

![Bağlantılı Liste Nedir? [Bölüm 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































