Web DevelopmentTypeScriptJavaScriptFonksiyonlar

TypeScript Dersleri 3 - Fonksiyon Parametreleri

Masum Gökyüz

June 26, 2023

905 words5 min read––– views

No BS TS Notları 3 - Fonksiyonlar ve Fonksiyon Parametreleri

No BS TS Notları 3 - Fonksiyonlar ve Fonksiyon Parametreleri

Function Parameters

Diyelim ki bir fonksiyon oluşturmak istiyorsunuz ve bu fonksiyonun `callback desteklemesini istiyorsunuz. Örneğin, bir dosyaya yazma fonksiyonu oluşturmak istediğinizi düşünelim.

export function printToFile(text: string, callback: () => void): void { console.log(text); callback(); }

Bu fonksiyon birinci parametresine text adında bir string alıyor ve ikinci parametresine callback adında bir fonksiyon alıyor. Bu callback fonksiyonu void döndürüyor. Aynı şekilde printToFile fonksiyonu da void döndürüyor. Yani, bize bir şey return Bu fonksiyonu kullanmak için aşağıdaki gibi kullanabilirsiniz.

printToFile("Hi, there!", () => console.log("Callback"));

Bu fonksiyonun çıktısı, yani output'u şu şekilde olacaktır:

Hi, there! Callback

Function With Params

Parametre olarak number[] (sayı dizisi) alan bir array mutation function oluşturalım.

export function arrayMutate( numbers: number[], mutate: (v: number) => number ): number[] { return numbers.map(mutate); }

Bu fonksiyon numbers adında bir number[] ve mutate adında bir fonksiyon alıyor. mutate fonksiyonu kendi içerisinde bir parametre olarak number değeri (v) alıyor ve bir number döndürüyor ((v: number) => number). arrayMutate fonksiyonu da sonuç olarak bize number[] döndürüyor. En son olarak da bu fonksiyon bize numbers dizisini map fonksiyonu ile mutate fonksiyonuna gönderiyor. Örnek olarak aşağıdaki gibi kullanabiliriz.

console.log(arrayMutate([1, 2, 3], (v) => v * 10)); // Output: [10, 20, 30]

arrayMutate fonksiyonunu okumak ilk bakışta biraz zor olabilir. Bu yüzden bu fonksiyona atamak için yeni bir type oluşturalım ve daha sonrasında da fonksiyona atayalım.

type MutationFunction = (v: number) => number; export function arrayMutateButMoreReadable( numbers: number[], mutate: MutationFunction ): number[] { return numbers.map(mutate); }

Bu şekilde daha okunabilir bir hale geldi.


Ayrıca arrow function oluşturduğumuzda da bu typeı aşağıdaki gibi kullanabiliriz:

export const myNewMutation: MutationFunction = (v) => v * 100; console.log(myNewMutation(3)); // Output: 300

arrow function oluştururken typeı parametreleri yazarken de belirtebiliriz ancak bu okunuşu zaman zaman zorlaştırabilir. Örneğin:

const mutationArrowFunction = (n: number[], mutate: (v: number) => number): number[] => { return n.map(mutate); } console.log(mutationArrowFunction([1, 2, 3], (v) => v * 10)); // Output: [10, 20, 30]

Aynı fonksiyonu yeni bir type oluşturarak yazalım:

type ArrowFunctionMutation = (numbers: number[], mutate: (v: number) => number) => number[]; const mutationArrowFunctionButMoreReadable: ArrowFunctionMutation = (n, mutate) => { return n.map(mutate); } console.log(mutationArrowFunctionButMoreReadable([1, 2, 3], (v) => v * 10)); // Output: [10, 20, 30]

Bu şekilde daha okunabilir bir hale geldiğini söyleyebiliriz.


İşleri biraz daha karmaşıklaştırıp arrow functionın typeını tanımlarken bir object olarak da type verebiliriz. Örneğin:

type ArrowFunctionMutationButAsObject = { numbers: number[]; mutate: (v: number) => number; }; export const arrowFunctionMutationButObject = (data: ArrowFunctionMutationButAsObject): number[] => { return data.numbers.map(data.mutate); } console.log(arrowFunctionMutationButObject({ numbers: [1, 2, 3], mutate: (v) => v * 10 })); // Output: [10, 20, 30]

Gördüğünüz üzere, bu sefer arrowFunctionMutationButObject adındaki fonksiyona parametre olarak bir object verdik. Bu objectin içerisinde numbers ve mutate adında iki adet property var. numbers adındaki property bir number[] alıyor ve mutate adındaki property bir (v: number) => number alıyor. Bu objecti fonksiyonumuza parametre olarak verdiğimizde de numbers ve mutate adındaki propertyleri map fonksiyonuna parametre olarak veriyoruz. Bu fonksiyon da bize sonuç olarak bir sayı dizisi (number[]) döndürüyor.


Returning Functions

Bir fonksiyonun dönüş değeri olarak başka bir fonksiyon döndürebiliriz. Klasik bir JavaScript closure örneği olarak aşağıdaki fonksiyonu yazabiliriz:

export function createAdder(num: number) { return (val: number) => num + val; } const addOne = createAdder(1); console.log(addOne(55)); // Output: 56

İlk olarak createAdder adında bir fonksiyon oluşturduk ve bu fonksiyon parametre olarak bir num (number) alıyor. Ardından bize return değeri olarak bir arrow function döndürüyor. Bu arrow function da bir val (number) alıyor ve bu val değerini num ile toplayıp sonucu döndürüyor. Daha sonrasında addOne adında bir değişken oluşturduk ve bu değişken içerisinde createAdder fonksiyonunu 1 parametresi ile çağırdık. Bu fonksiyon bize bir arrow function döndürdüğü için addOne adındaki değişken aslında bir arrow function olmuş oldu. Daha sonrasında da addOne fonksiyonunu 55 parametresi ile çağırdık ve sonucu ekrana yazdırdık. Ancak createAdder fonksiyonunun return typeını belirlemedik. Bu fonksiyonun nasıl bir return typeına sahip olduğunu görmek için VSCode'da bu fonksiyonun üzerine gelebiliriz ve return typeını görebiliriz (çünkü TypeScript bize bu fonksiyonun typeını infer edebiliyor): function createAdder(num: number): (val: number) => number. Öyleyse bunu kopyalayıp fonksiyonumuza yapıştıralım:

export function createAdder(num: number): (val: number) => number { return (val: number) => num + val; }

Bu şekilde fonksiyonumuzun return typeını da belirlemiş olduk.


Eğer bu fonksiyonun okunuşu biraz zor geliyorsa, typeını bir değişkene atayabiliriz:

type AdderFunction = (val: number) => number; export function createAdderButMoreReadable(num: number): AdderFunction { return (val: number) => num + val; }

Bu şekilde daha okunabilir bir hale geldiğini söyleyebiliriz.

Not Playing

Spotify

Built with://

GitHubLinkedInEmail