{"id":33946,"date":"2025-11-09T05:40:48","date_gmt":"2025-11-09T02:40:48","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=33946"},"modified":"2025-11-09T05:40:48","modified_gmt":"2025-11-09T02:40:48","slug":"typescriptte-generics-kullanimi-derinlemesine-bir-rehber","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/","title":{"rendered":"TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber"},"content":{"rendered":"<p><body><\/p>\n<h2>TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber<\/h2>\n<h2>Giri\u015f<\/h2>\n<p>Modern web uygulamalar\u0131 geli\u015ftirirken, kodun okunabilirli\u011fi, bak\u0131m\u0131 ve \u00f6zellikle de g\u00fcvenilirli\u011fi b\u00fcy\u00fck \u00f6nem ta\u015f\u0131r. JavaScript&#8217;in dinamik yap\u0131s\u0131, esneklik sa\u011flarken, b\u00fcy\u00fck \u00f6l\u00e7ekli projelerde tip hatalar\u0131na ve beklenmedik davran\u0131\u015flara yol a\u00e7abilir. \u0130\u015fte bu noktada TypeScript devreye girer. TypeScript, JavaScript&#8217;e statik tipleme yetene\u011fi kazand\u0131rarak, geli\u015ftiricilerin kodlar\u0131n\u0131 daha g\u00fcvenli ve \u00f6ng\u00f6r\u00fclebilir hale getirmelerini sa\u011flar. Derleme zaman\u0131nda tip kontrol\u00fc yaparak olas\u0131 hatalar\u0131 \u00e7al\u0131\u015fma zaman\u0131ndan \u00f6nce tespit etmemize olanak tan\u0131r.<\/p>\n<p>TypeScript&#8217;in sundu\u011fu en g\u00fc\u00e7l\u00fc \u00f6zelliklerden biri de &#8220;Generics&#8221;tir. Generics, bile\u015fenleri (fonksiyonlar, s\u0131n\u0131flar, aray\u00fczler) belirli bir veri tipiyle de\u011fil, genel bir veri tipiyle \u00e7al\u0131\u015facak \u015fekilde tasarlamam\u0131z\u0131 sa\u011flar. Bu sayede, ayn\u0131 kodu farkl\u0131 veri tipleriyle tekrar tekrar kullanabiliriz, ancak bunu yaparken tip g\u00fcvenli\u011fini kaybetmeyiz. Generics, kod tekrar\u0131n\u0131 azalt\u0131r, kodun daha esnek olmas\u0131n\u0131 sa\u011flar ve geli\u015ftiricilere g\u00fc\u00e7l\u00fc, tip g\u00fcvenli ve yeniden kullan\u0131labilir bile\u015fenler olu\u015fturma yetene\u011fi sunar. Bu makalede, TypeScript Generics&#8217;in ne oldu\u011funu, neden bu kadar \u00f6nemli oldu\u011funu, farkl\u0131 kullan\u0131m alanlar\u0131n\u0131 ve ileri seviye senaryolar\u0131n\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Amac\u0131m\u0131z, Generics&#8217;i derinlemesine anlayarak TypeScript projelerinizde etkin bir \u015fekilde kullanabilmeniz i\u00e7in size kapsaml\u0131 bir rehber sunmakt\u0131r.<\/p>\n<h2>Generics Nedir? Neden \u0130htiya\u00e7 Duyar\u0131z?<\/h2>\n<p>Generics&#8217;in ne oldu\u011funu anlamak i\u00e7in, \u00f6ncelikle onun \u00e7\u00f6zd\u00fc\u011f\u00fc problemi kavramak \u00f6nemlidir. Tip g\u00fcvenli\u011fini korurken esnek kod yazma ihtiyac\u0131, Generics&#8217;in ortaya \u00e7\u0131k\u0131\u015f nedenidir.<\/p>\n<h3>Sorun: Tekrar Eden Kodlar ve Tip G\u00fcvenli\u011fi Eksikli\u011fi<\/h3>\n<p>Bir fonksiyonun ald\u0131\u011f\u0131 de\u011feri oldu\u011fu gibi geri d\u00f6nd\u00fcren basit bir &#8220;identity&#8221; (\u00f6zde\u015flik) fonksiyonu d\u00fc\u015f\u00fcnelim. Bu fonksiyonu farkl\u0131 tiplerle \u00e7al\u0131\u015ft\u0131rmak istedi\u011fimizde ne olur?<\/p>\n<p>\u0130lk akla gelen y\u00f6ntemlerden biri, JavaScript&#8217;te oldu\u011fu gibi hi\u00e7bir tip belirtmemek veya TypeScript&#8217;in <code>any<\/code> tipini kullanmakt\u0131r:<\/p>\n<pre><code class=\"language-typescript\">function identityAny(arg: any): any {\n  return arg;\n}\n\nlet output1 = identityAny(\"myString\"); \/\/ output1 tipi: any\nlet output2 = identityAny(123);      \/\/ output2 tipi: any\n\nconsole.log(output1.length); \/\/ \u00c7al\u0131\u015f\u0131r\nconsole.log(output2.length); \/\/ \u00c7al\u0131\u015fma zaman\u0131 hatas\u0131: undefined (number'\u0131n length \u00f6zelli\u011fi yok)<\/code><\/pre>\n<p>Bu \u00f6rnekte <code>identityAny<\/code> fonksiyonu, herhangi bir tipteki de\u011feri kabul edip geri d\u00f6nd\u00fcrebilir. Ancak <code>any<\/code> tipi kullanmak, TypeScript&#8217;in tip kontrol mekanizmas\u0131n\u0131 devre d\u0131\u015f\u0131 b\u0131rak\u0131r. Fonksiyona verilen <code>123<\/code> bir say\u0131 olmas\u0131na ra\u011fmen, TypeScript <code>output2<\/code>&#8216;nin tipini <code>any<\/code> olarak belirledi\u011fi i\u00e7in, <code>output2.length<\/code> ifadesine derleme zaman\u0131nda itiraz etmez. Bu, \u00e7al\u0131\u015fma zaman\u0131nda beklenmedik hatalara yol a\u00e7abilir. <code>any<\/code> tipi, tip g\u00fcvenli\u011fini tamamen ortadan kald\u0131r\u0131r ve TypeScript kullanman\u0131n temel faydalar\u0131ndan birini kaybetmemize neden olur.<\/p>\n<p>Peki ya her tip i\u00e7in ayr\u0131 bir fonksiyon yazsayd\u0131k?<\/p>\n<pre><code class=\"language-typescript\">function identityString(arg: string): string {\n  return arg;\n}\n\nfunction identityNumber(arg: number): number {\n  return arg;\n}\n\n\/\/ ... ve di\u011fer t\u00fcm tipler i\u00e7in<\/code><\/pre>\n<p>Bu yakla\u015f\u0131m, kod tekrar\u0131na yol a\u00e7ar ve \u00f6l\u00e7eklenebilir de\u011fildir. Her yeni tip i\u00e7in yeni bir fonksiyon yazmak zorunda kal\u0131r\u0131z. Bu, karma\u015f\u0131k projelerde s\u00fcrd\u00fcr\u00fclebilir bir \u00e7\u00f6z\u00fcm de\u011fildir.<\/p>\n<h3>\u00c7\u00f6z\u00fcm: Generics<\/h3>\n<p>\u0130\u015fte burada Generics devreye girer. Generics, bir bile\u015feni (fonksiyon, s\u0131n\u0131f veya aray\u00fcz) belirli bir tip \u00fczerinde de\u011fil, bir &#8220;tip de\u011fi\u015fkeni&#8221; \u00fczerinde \u00e7al\u0131\u015facak \u015fekilde tasarlamam\u0131z\u0131 sa\u011flar. Bu tip de\u011fi\u015fkeni, bile\u015fen \u00e7a\u011fr\u0131l\u0131rken ger\u00e7ek bir tiple de\u011fi\u015ftirilir. Bu sayede, ayn\u0131 kodu farkl\u0131 tiplerle kullanabiliriz ve en \u00f6nemlisi, tip g\u00fcvenli\u011fini koruruz.<\/p>\n<p>Generics kullan\u0131larak yaz\u0131lm\u0131\u015f bir <code>identity<\/code> fonksiyonu \u015f\u00f6yle g\u00f6r\u00fcn\u00fcr:<\/p>\n<pre><code class=\"language-typescript\">function identity<T>(arg: T): T {\n  return arg;\n}\n\n\/\/ Fonksiyonu \u00e7a\u011f\u0131r\u0131rken tip otomatik olarak \u00e7\u0131kar\u0131l\u0131r:\nlet outputString = identity(\"myString\"); \/\/ outputString tipi: string\nlet outputNumber = identity(123);      \/\/ outputNumber tipi: number\n\nconsole.log(outputString.length); \/\/ \u00c7al\u0131\u015f\u0131r, TypeScript bilir ki outputString bir string'dir.\n\/\/ console.log(outputNumber.length); \/\/ Hata: 'number' tipinde 'length' \u00f6zelli\u011fi yok.\n                                   \/\/ TypeScript derleme zaman\u0131nda bu hatay\u0131 yakalar.\n\n\/\/ \u0130ste\u011fe ba\u011fl\u0131 olarak tipi a\u00e7\u0131k\u00e7a belirtebiliriz:\nlet outputBoolean = identity<boolean>(true); \/\/ outputBoolean tipi: boolean<\/code><\/pre>\n<p>Bu \u00f6rnekte:<br \/>\n*   <code><T><\/code> ifadesi, <code>T<\/code> ad\u0131nda bir tip de\u011fi\u015fkeni tan\u0131mlar. <code>T<\/code>, &#8220;Type&#8221; kelimesinden gelir ve yayg\u0131n olarak kullan\u0131lan bir isimlendirme kural\u0131d\u0131r, ancak herhangi bir ge\u00e7erli tan\u0131mlay\u0131c\u0131 kullanabilirsiniz (\u00f6rne\u011fin <code><Type><\/code>, <code><Element><\/code>, <code><Value><\/code>).<br \/>\n*   <code>arg: T<\/code> parametrenin tipinin <code>T<\/code> oldu\u011funu belirtir.<br \/>\n*   <code>: T<\/code> fonksiyonun d\u00f6n\u00fc\u015f tipinin de <code>T<\/code> oldu\u011funu belirtir.<\/p>\n<p>Bu sayede, <code>identity<\/code> fonksiyonunu \u00e7a\u011f\u0131r\u0131rken, TypeScript <code>T<\/code> tip de\u011fi\u015fkenini verdi\u011fimiz arg\u00fcman\u0131n ger\u00e7ek tipiyle de\u011fi\u015ftirir. <code>identity(\"myString\")<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda, <code>T<\/code> <code>string<\/code> olur. <code>identity(123)<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda, <code>T<\/code> <code>number<\/code> olur. Fonksiyonun i\u00e7indeki i\u015flemler bu ger\u00e7ek tipler \u00fczerinden tip kontrol\u00fcne tabi tutulur. Bu da bize hem esneklik hem de g\u00fc\u00e7l\u00fc tip g\u00fcvenli\u011fi sa\u011flar.<\/p>\n<p>Generics&#8217;in temel faydalar\u0131 \u015funlard\u0131r:<br \/>\n1.  <strong>Tip G\u00fcvenli\u011fi (Type Safety):<\/strong> <code>any<\/code> kullanmadan, farkl\u0131 tiplerle \u00e7al\u0131\u015f\u0131rken bile derleme zaman\u0131nda tip hatalar\u0131n\u0131 yakalamay\u0131 sa\u011flar.<br \/>\n2.  <strong>Kod Tekrar\u0131n\u0131 Azaltma (Reduced Code Duplication):<\/strong> Ayn\u0131 mant\u0131\u011f\u0131 farkl\u0131 tipler i\u00e7in tekrar tekrar yazmak yerine, generic bir bile\u015fen olu\u015fturulabilir.<br \/>\n3.  <strong>Esneklik ve Yeniden Kullan\u0131labilirlik (Flexibility and Reusability):<\/strong> Bile\u015fenlerinizi daha genel hale getirerek, daha geni\u015f bir yelpazedeki senaryolarda kullan\u0131labilir olmas\u0131n\u0131 sa\u011flar.<br \/>\n4.  <strong>Geli\u015ftirici Deneyimi (Developer Experience):<\/strong> Otomatik tamamlama (autocompletion) ve tip \u00e7\u0131kar\u0131m\u0131 sayesinde daha iyi bir geli\u015ftirme deneyimi sunar.<\/p>\n<h2>Generics Kullan\u0131m Alanlar\u0131<\/h2>\n<p>Generics, TypeScript&#8217;in bir\u00e7ok farkl\u0131 yerinde kullan\u0131labilir: fonksiyonlarda, aray\u00fczlerde, tip alias&#8217;lar\u0131nda ve s\u0131n\u0131flarda. Her bir kullan\u0131m alan\u0131n\u0131 detayl\u0131ca inceleyelim.<\/p>\n<h3>Fonksiyonlarda Generics<\/h3>\n<p>Fonksiyonlarda Generics kullan\u0131m\u0131, belki de en yayg\u0131n ve anla\u015f\u0131lmas\u0131 kolay senaryodur. Daha \u00f6nce g\u00f6rd\u00fc\u011f\u00fcm\u00fcz <code>identity<\/code> fonksiyonu bunun g\u00fczel bir \u00f6rne\u011fidir.<\/p>\n<pre><code class=\"language-typescript\">\/\/ Basit bir generic fonksiyon\nfunction identity<T>(arg: T): T {\n  return arg;\n}\n\nlet result1 = identity<string>(\"Merhaba D\u00fcnya\"); \/\/ T = string\nlet result2 = identity<number>(42);           \/\/ T = number\nlet result3 = identity(true);                 \/\/ T = boolean (tip \u00e7\u0131kar\u0131m\u0131 ile)\n\nconsole.log(result1.toUpperCase()); \/\/ \"MERHABA D\u00dcNYA\"\n\/\/ console.log(result2.toFixed(2));   \/\/ \"42.00\"<\/code><\/pre>\n<h4>Birden Fazla Generic Tip De\u011fi\u015fkeni<\/h4>\n<p>Bir fonksiyon birden fazla generic tip de\u011fi\u015fkeni de alabilir:<\/p>\n<pre><code class=\"language-typescript\">function merge<T, U>(obj1: T, obj2: U): T & U {\n  return { ...obj1, ...obj2 };\n}\n\nlet mergedObject = merge({ name: \"Alice\" }, { age: 30 });\n\/\/ mergedObject'in tipi: { name: string; } & { age: number; } yani { name: string; age: number; }\n\nconsole.log(mergedObject.name); \/\/ Alice\nconsole.log(mergedObject.age);  \/\/ 30<\/code><\/pre>\n<p>Burada <code>T<\/code> ve <code>U<\/code> iki farkl\u0131 generic tipi temsil eder. Fonksiyonun d\u00f6n\u00fc\u015f tipi <code>T & U<\/code> (intersection type), iki objenin \u00f6zelliklerini birle\u015ftiren yeni bir tip olu\u015fturur.<\/p>\n<h4>Generic Tiplerle \u00c7al\u0131\u015f\u0131rken K\u0131s\u0131tlamalar (Constraints)<\/h4>\n<p>Bazen generic tiplerle \u00e7al\u0131\u015f\u0131rken, bu tiplerin belirli \u00f6zelliklere sahip olmas\u0131n\u0131 isteriz. \u00d6rne\u011fin, bir fonksiyonun bir arg\u00fcman\u0131n <code>length<\/code> \u00f6zelli\u011fine sahip olmas\u0131n\u0131 bekledi\u011fini varsayal\u0131m. E\u011fer <code>T<\/code> tipinin herhangi bir \u015fey olabilece\u011fini varsayarsak, <code>T.length<\/code> ifadesi hata verebilir (\u00f6rne\u011fin, bir say\u0131 tipinin <code>length<\/code> \u00f6zelli\u011fi yoktur). Bu durumu <code>extends<\/code> anahtar kelimesi ile k\u0131s\u0131tlayabiliriz.<\/p>\n<pre><code class=\"language-typescript\">interface Lengthwise {\n  length: number;\n}\n\nfunction loggingIdentity<T extends Lengthwise>(arg: T): T {\n  console.log(arg.length); \/\/ Art\u0131k T'nin length \u00f6zelli\u011fine sahip oldu\u011funu biliyoruz.\n  return arg;\n}\n\nloggingIdentity(\"hello\"); \/\/ length: 5\nloggingIdentity([1, 2, 3]); \/\/ length: 3\n\/\/ loggingIdentity(42); \/\/ Hata: 'number' tipinde 'length' \u00f6zelli\u011fi yok.<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>T extends Lengthwise<\/code> diyerek, <code>T<\/code> tipinin <code>Lengthwise<\/code> aray\u00fcz\u00fcndeki t\u00fcm \u00f6zelliklere (yani <code>length<\/code> \u00f6zelli\u011fine) sahip olmas\u0131 gerekti\u011fini belirtiyoruz.<\/p>\n<p>Ba\u015fka bir yayg\u0131n k\u0131s\u0131tlama senaryosu, bir objenin belirli bir \u00f6zelli\u011fine eri\u015fmek istedi\u011fimizde ortaya \u00e7\u0131kar:<\/p>\n<pre><code class=\"language-typescript\">function getProperty<T, K extends keyof T>(obj: T, key: K) {\n  return obj[key];\n}\n\nlet user = { id: 1, name: \"Bob\", email: \"bob@example.com\" };\n\nlet userName = getProperty(user, \"name\"); \/\/ userName tipi: string\nlet userId = getProperty(user, \"id\");     \/\/ userId tipi: number\n\/\/ let userAddress = getProperty(user, \"address\"); \/\/ Hata: 'address' user tipinde yok.<\/code><\/pre>\n<p>Burada <code>K extends keyof T<\/code> ifadesi, <code>K<\/code>&#8216;n\u0131n <code>T<\/code> tipinin bir anahtar\u0131 (property ismi) olmas\u0131 gerekti\u011fini belirtir. Bu, <code>obj[key]<\/code> eri\u015fiminin tip g\u00fcvenli\u011fini sa\u011flar.<\/p>\n<h4>Default Generic Tipler<\/h4>\n<p>TypeScript 2.3&#8217;ten itibaren, generic tiplere varsay\u0131lan de\u011ferler atayabiliriz. Bu, generic tipin belirtilmedi\u011fi durumlarda bir yedek tip sa\u011flar.<\/p>\n<pre><code class=\"language-typescript\">interface APIResponse<T = any> { \/\/ T belirtilmezse default olarak any kullan\u0131l\u0131r.\n  data: T;\n  status: number;\n  message?: string;\n}\n\nlet response1: APIResponse<string> = { data: \"Success\", status: 200 };\nlet response2: APIResponse = { data: { id: 1, name: \"Item\" }, status: 200 }; \/\/ T = any\nlet response3: APIResponse<number[]> = { data: [10, 20, 30], status: 200 };<\/code><\/pre>\n<h3>\u0130nterface&#8217;lerde Generics<\/h3>\n<p>Aray\u00fczler de generic olabilir ve bu, veri yap\u0131lar\u0131 veya API yan\u0131tlar\u0131 gibi genel yap\u0131lar tan\u0131mlamak i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<pre><code class=\"language-typescript\">interface Box<T> {\n  value: T;\n}\n\nlet stringBox: Box<string> = { value: \"Hello\" };\nlet numberBox: Box<number> = { value: 123 };\n\nconsole.log(stringBox.value.length); \/\/ 5\n\/\/ console.log(numberBox.value.toUpperCase()); \/\/ Hata: 'number' tipinde 'toUpperCase' yok.\n\ninterface KeyValuePair<K, V> {\n  key: K;\n  value: V;\n}\n\nlet userConfig: KeyValuePair<string, number> = { key: \"theme\", value: 1 };\nlet productInfo: KeyValuePair<number, { name: string, price: number }> = {\n  key: 101,\n  value: { name: \"Laptop\", price: 1200 }\n};<\/code><\/pre>\n<p>Generic aray\u00fczler, belirli bir veri yap\u0131s\u0131n\u0131n i\u00e7indeki elemanlar\u0131n tipini esnek bir \u015fekilde tan\u0131mlamam\u0131z\u0131 sa\u011flar. \u00d6rne\u011fin, bir veri listesi veya bir API yan\u0131t\u0131n\u0131n veri y\u00fck\u00fc (payload) i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<h3>Type Aliases&#8217;larda Generics<\/h3>\n<p>Aray\u00fczlere benzer \u015fekilde, tip alias&#8217;lar\u0131 da generic olabilir.<\/p>\n<pre><code class=\"language-typescript\">type Pair<T, U> = {\n  first: T;\n  second: U;\n};\n\nlet myPair: Pair<string, number> = { first: \"age\", second: 30 };\nlet anotherPair: Pair<boolean, string[]> = { first: true, second: [\"apple\", \"banana\"] };\n\ntype CallbackFunction<T, R> = (arg: T) => R;\n\nconst processString: CallbackFunction<string, number> = (str) => str.length;\nconsole.log(processString(\"TypeScript\")); \/\/ 10<\/code><\/pre>\n<p>Generic type alias&#8217;lar, genellikle aray\u00fczlerle benzer ama\u00e7lar i\u00e7in kullan\u0131l\u0131r, ancak fonksiyon tipleri veya union\/intersection tipleri gibi daha karma\u015f\u0131k tip kombinasyonlar\u0131n\u0131 tan\u0131mlamak i\u00e7in daha esnektirler.<\/p>\n<h3>S\u0131n\u0131flarda Generics<\/h3>\n<p>S\u0131n\u0131flar da generic olabilir. Bu, koleksiyonlar, veri yap\u0131lar\u0131 veya fabrika desenleri gibi tipten ba\u011f\u0131ms\u0131z s\u0131n\u0131flar olu\u015fturmak i\u00e7in idealdir.<\/p>\n<pre><code class=\"language-typescript\">class GenericStack<T> {\n  private elements: T[] = [];\n\n  push(element: T): void {\n    this.elements.push(element);\n  }\n\n  pop(): T | undefined {\n    return this.elements.pop();\n  }\n\n  isEmpty(): boolean {\n    return this.elements.length === 0;\n  }\n\n  size(): number {\n    return this.elements.length;\n  }\n}\n\nlet numberStack = new GenericStack<number>();\nnumberStack.push(10);\nnumberStack.push(20);\nconsole.log(numberStack.pop()); \/\/ 20 (tip: number)\n\nlet stringStack = new GenericStack<string>();\nstringStack.push(\"A\");\nstringStack.push(\"B\");\nconsole.log(stringStack.pop()); \/\/ \"B\" (tip: string)<\/code><\/pre>\n<p>Bir ba\u015fka \u00f6rnek, bir veri taban\u0131 deposu (repository) s\u0131n\u0131f\u0131 olabilir:<\/p>\n<pre><code class=\"language-typescript\">interface HasId {\n  id: number;\n}\n\nclass Repository<T extends HasId> {\n  private items: T[] = [];\n\n  add(item: T): void {\n    this.items.push(item);\n  }\n\n  findById(id: number): T | undefined {\n    return this.items.find(item => item.id === id);\n  }\n\n  getAll(): T[] {\n    return [...this.items];\n  }\n}\n\ninterface User extends HasId {\n  name: string;\n  email: string;\n}\n\nlet userRepository = new Repository<User>();\nuserRepository.add({ id: 1, name: \"Ali\", email: \"ali@example.com\" });\nuserRepository.add({ id: 2, name: \"Veli\", email: \"veli@example.com\" });\n\nlet ali = userRepository.findById(1);\nconsole.log(ali?.name); \/\/ Ali<\/code><\/pre>\n<p>Burada <code>Repository<T extends HasId><\/code> diyerek, <code>T<\/code> tipinin mutlaka bir <code>id: number<\/code> \u00f6zelli\u011fine sahip olmas\u0131 gerekti\u011fini belirtiyoruz. Bu, <code>findById<\/code> metodunun <code>item.id<\/code>&#8216;ye g\u00fcvenle eri\u015febilmesini sa\u011flar.<\/p>\n<p><strong>\u00d6nemli Not:<\/strong> Static \u00fcyeler generic tip de\u011fi\u015fkenlerini kullanamazlar. Bir s\u0131n\u0131f\u0131n generic tipi, s\u0131n\u0131f\u0131n instance&#8217;\u0131 olu\u015fturuldu\u011funda belirlenirken, static \u00fcyeler instance&#8217;tan ba\u011f\u0131ms\u0131zd\u0131r.<\/p>\n<h3>Generic Tiplerle \u00c7al\u0131\u015fan Fonksiyon Tipleri<\/h3>\n<p>Bazen, generic bir fonksiyonun kendisini bir tip olarak tan\u0131mlamak isteyebiliriz. Bu, \u00f6zellikle callback fonksiyonlar\u0131 veya fonksiyon imzalar\u0131n\u0131 tan\u0131mlarken faydal\u0131d\u0131r.<\/p>\n<pre><code class=\"language-typescript\">interface GenericIdentityFn<T> {\n  (arg: T): T;\n}\n\nfunction identity<T>(arg: T): T {\n  return arg;\n}\n\nlet myIdentity: GenericIdentityFn<number> = identity;\n\nconsole.log(myIdentity(100)); \/\/ 100\n\/\/ console.log(myIdentity(\"hello\")); \/\/ Hata: 'string' tipi 'number' tipine atanamaz.<\/code><\/pre>\n<p>Bu \u00f6rnekte <code>GenericIdentityFn<T><\/code> aray\u00fcz\u00fc, <code>T<\/code> tipinde bir arg\u00fcman al\u0131p <code>T<\/code> tipinde bir de\u011fer d\u00f6nd\u00fcren herhangi bir fonksiyonun imzas\u0131n\u0131 temsil eder. <code>myIdentity<\/code> de\u011fi\u015fkeni bu aray\u00fcz\u00fc <code>number<\/code> tipiyle uygulad\u0131\u011f\u0131 i\u00e7in, sadece <code>number<\/code> tipinde arg\u00fcmanlar\u0131 kabul eder.<\/p>\n<h3>Generic K\u0131s\u0131tlamalar (Generic Constraints) Detayl\u0131 \u0130nceleme<\/h3>\n<p>Generic k\u0131s\u0131tlamalar, generic tiplerin alabilece\u011fi de\u011ferleri daraltarak daha spesifik ve g\u00fcvenli kod yazmam\u0131z\u0131 sa\u011flar. <code>extends<\/code> anahtar kelimesi ile kullan\u0131l\u0131rlar.<\/p>\n<p>*   <strong>Belirli bir property&#8217;ye sahip olma k\u0131s\u0131tlamas\u0131:<\/strong> Daha \u00f6nce g\u00f6rd\u00fc\u011f\u00fcm\u00fcz <code>Lengthwise<\/code> \u00f6rne\u011fi gibi.<\/p>\n<pre><code class=\"language-typescript\">interface Product {\n      name: string;\n      price: number;\n    }\n\n    function displayProductInfo<T extends Product>(item: T): void {\n      console.log(<code>Product Name: ${item.name}, Price: $${item.price}<\/code>);\n    }\n\n    displayProductInfo({ name: \"Laptop\", price: 1200, category: \"Electronics\" }); \/\/ \u00c7al\u0131\u015f\u0131r\n    \/\/ displayProductInfo({ id: 1, stock: 10 }); \/\/ Hata: 'Product' tipine atanabilir de\u011fil.<\/code><\/pre>\n<p>*   <strong>Ba\u015fka bir generic tip ile k\u0131s\u0131tlama:<\/strong> Bir generic tipin ba\u015fka bir generic tipin alt tipi olmas\u0131n\u0131 sa\u011flayabiliriz.<\/p>\n<pre><code class=\"language-typescript\">function copyFields<T extends U, U>(target: T, source: U): T {\n      for (let id in source) {\n        \/\/ target[id] = source[id]; \/\/ Hata: 'id' keyof T de\u011fil.\n        \/\/ Bu t\u00fcr atamalar i\u00e7in daha dikkatli olmak gerekir.\n        \/\/ \u00d6rne\u011fin, source'un t\u00fcm key'lerinin target'ta da oldu\u011funu garanti etmek zor olabilir.\n      }\n      return target;\n    }\n\n    let x = { a: 1, b: 2, c: 3, d: 4 };\n    let y = { a: 5, b: 6 };\n\n    \/\/ copyFields(x, y); \/\/ x (T) U'dan (y) daha fazla property'ye sahip olabilir.\n                       \/\/ Ama\u00e7, U'nun t\u00fcm property'lerinin T'de de olmas\u0131n\u0131 sa\u011flamak.\n                       \/\/ Bu \u00f6rnekte, T extends U, U'nun T'nin alt k\u00fcmesi oldu\u011funu belirtir.\n                       \/\/ Yani T, U'daki t\u00fcm property'lere sahip olmal\u0131 ve muhtemelen fazlas\u0131na.<\/code><\/pre>\n<p>    Bu \u00f6rnek karma\u015f\u0131k olabilir. Daha basit bir \u00f6rnek:<\/p>\n<pre><code class=\"language-typescript\">interface Named { name: string; }\n    function greet<T extends Named>(entity: T): string {\n      return <code>Hello, ${entity.name}<\/code>;\n    }\n\n    greet({ name: \"Alice\", age: 30 }); \/\/ \u00c7al\u0131\u015f\u0131r\n    \/\/ greet({ age: 25 }); \/\/ Hata: 'name' \u00f6zelli\u011fi eksik.<\/code><\/pre>\n<p>*   <strong>Constructor k\u0131s\u0131tlamas\u0131 (<code>new () => T<\/code>):<\/strong> Bir s\u0131n\u0131f\u0131n generic olarak \u00f6rne\u011fini olu\u015fturmak istedi\u011fimizde kullan\u0131l\u0131r. Bu, fabrika (factory) fonksiyonlar\u0131 yazarken \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<pre><code class=\"language-typescript\">class Car {\n      constructor(public brand: string) {}\n      drive() { console.log(<code>${this.brand} is driving.<\/code>); }\n    }\n\n    class Motorcycle {\n      constructor(public model: string) {}\n      ride() { console.log(<code>${this.model} is riding.<\/code>); }\n    }\n\n    function createInstance<T>(constructor: new (...args: any[]) => T, ...args: any[]): T {\n      return new constructor(...args);\n    }\n\n    let myCar = createInstance(Car, \"BMW\");\n    myCar.drive(); \/\/ BMW is driving.\n\n    let myMotorcycle = createInstance(Motorcycle, \"Harley\");\n    myMotorcycle.ride(); \/\/ Harley is riding.<\/code><\/pre>\n<p>    Burada <code>constructor: new (...args: any[]) => T<\/code> ifadesi, <code>constructor<\/code> parametresinin, <code>T<\/code> tipinde bir instance d\u00f6nd\u00fcren bir constructor fonksiyonu olmas\u0131 gerekti\u011fini belirtir.<\/p>\n<h3><code>keyof<\/code> ve <code>typeof<\/code> ile Generic K\u0131s\u0131tlamalar<\/h3>\n<p><code>keyof<\/code> operat\u00f6r\u00fc, bir tipin t\u00fcm anahtar isimlerinin union tipini d\u00f6nd\u00fcr\u00fcr. Generics ile birle\u015fti\u011finde, bir objenin belirli bir anahtar\u0131na g\u00fcvenli bir \u015fekilde eri\u015fmek i\u00e7in harika bir ara\u00e7t\u0131r.<\/p>\n<pre><code class=\"language-typescript\">function getDeepProperty<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2] {\n  return obj[key1][key2];\n}\n\nconst userProfile = {\n  id: 1,\n  details: {\n    name: \"John Doe\",\n    age: 30,\n    address: {\n      city: \"New York\",\n      zip: \"10001\"\n    }\n  }\n};\n\nlet userName = getDeepProperty(userProfile, \"details\", \"name\"); \/\/ userName: string\nlet userCity = getDeepProperty(userProfile, \"details\", \"address\"); \/\/ userCity: { city: string, zip: string }\n\/\/ let userInvalid = getDeepProperty(userProfile, \"details\", \"invalid\"); \/\/ Hata: 'invalid' 'details' tipinde yok.<\/code><\/pre>\n<p><code>typeof<\/code> operat\u00f6r\u00fc, bir de\u011fi\u015fkenin veya \u00f6zelli\u011fin tipini d\u00f6nd\u00fcr\u00fcr. Generic ba\u011flamda, genellikle bir objenin yap\u0131s\u0131n\u0131 bir tip olarak kullanmak i\u00e7in kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-typescript\">const MY_CONFIG = {\n  apiUrl: \"https:\/\/api.example.com\",\n  timeout: 5000,\n  debugMode: true\n};\n\ntype ConfigType = typeof MY_CONFIG; \/\/ ConfigType: { apiUrl: string; timeout: number; debugMode: boolean; }\n\nfunction updateConfig<T extends ConfigType, K extends keyof T>(config: T, key: K, value: T[K]): T {\n  return { ...config, [key]: value };\n}\n\nlet newConfig = updateConfig(MY_CONFIG, \"timeout\", 10000);\nconsole.log(newConfig.timeout); \/\/ 10000\n\n\/\/ let invalidUpdate = updateConfig(MY_CONFIG, \"timeout\", \"20000\"); \/\/ Hata: 'string' 'number' tipine atanamaz.<\/code><\/pre>\n<h2>Geli\u015fmi\u015f Generic Kullan\u0131m Senaryolar\u0131<\/h2>\n<p>TypeScript&#8217;in utility tipleri ve geli\u015fmi\u015f tip sistem \u00f6zellikleri, Generics ile birle\u015fti\u011finde inan\u0131lmaz g\u00fc\u00e7l\u00fc ara\u00e7lar sunar.<\/p>\n<h3>Conditional Types ile Generics<\/h3>\n<p>Conditional Types (ko\u015fullu tipler), bir tipin ba\u015fka bir tipe atan\u0131p atanamayaca\u011f\u0131na ba\u011fl\u0131 olarak farkl\u0131 tipler se\u00e7memizi sa\u011flar. <code>T extends U ? X : Y<\/code> s\u00f6zdizimi ile tan\u0131mlan\u0131r. Generics ile birlikte kullan\u0131ld\u0131\u011f\u0131nda, dinamik ve esnek tip manip\u00fclasyonlar\u0131 yapmam\u0131z\u0131 sa\u011flar.<\/p>\n<pre><code class=\"language-typescript\">\/\/ Exclude<T, U> utility tipinin \u00e7al\u0131\u015fma mant\u0131\u011f\u0131na benzer\ntype MyExclude<T, U> = T extends U ? never : T;\n\ntype ValidColors = MyExclude<\"red\" | \"green\" | \"blue\" | \"black\", \"black\">; \/\/ \"red\" | \"green\" | \"blue\"\n\n\/\/ NonNullable<T> utility tipinin \u00e7al\u0131\u015fma mant\u0131\u011f\u0131na benzer\ntype MyNonNullable<T> = T extends null | undefined ? never : T;\n\ntype NullableString = string | null | undefined;\ntype NonNullableString = MyNonNullable<NullableString>; \/\/ string<\/code><\/pre>\n<p>Bu \u00f6rnekler, <code>T<\/code> tipinin <code>U<\/code> tipine atanabiliyor olup olmad\u0131\u011f\u0131na ba\u011fl\u0131 olarak bir tip se\u00e7er. Bu sayede, var olan tiplerden yeni tipler t\u00fcretebiliriz.<\/p>\n<h3>Mapped Types ile Generics<\/h3>\n<p>Mapped Types, var olan bir tipin \u00f6zelliklerini (keys) alarak yeni bir tip olu\u015fturmam\u0131z\u0131 sa\u011flar. Genellikle <code>[P in K]<\/code> s\u00f6zdizimi ile kullan\u0131l\u0131rlar. <code>keyof<\/code> operat\u00f6r\u00fc ile birle\u015fti\u011finde, bir objenin t\u00fcm \u00f6zelliklerini d\u00f6n\u00fc\u015ft\u00fcrebiliriz.<\/p>\n<pre><code class=\"language-typescript\">\/\/ Partial<T> utility tipinin \u00e7al\u0131\u015fma mant\u0131\u011f\u0131na benzer\ntype MyPartial<T> = {\n  [P in keyof T]?: T[P]; \/\/ T\u00fcm \u00f6zellikleri opsiyonel yapar\n};\n\ninterface UserProfile {\n  name: string;\n  email: string;\n  age: number;\n}\n\ntype PartialUserProfile = MyPartial<UserProfile>;\n\/\/ PartialUserProfile: { name?: string; email?: string; age?: number; }\n\n\/\/ Readonly<T> utility tipinin \u00e7al\u0131\u015fma mant\u0131\u011f\u0131na benzer\ntype MyReadonly<T> = {\n  readonly [P in keyof T]: T[P]; \/\/ T\u00fcm \u00f6zellikleri salt okunur yapar\n};\n\ntype ReadonlyUserProfile = MyReadonly<UserProfile>;\n\/\/ ReadonlyUserProfile: { readonly name: string; readonly email: string; readonly age: number; }\n\n\/\/ Kendi Mapped Type'\u0131m\u0131z\u0131 yazma \u00f6rne\u011fi:\ntype NullableProperties<T> = {\n  [P in keyof T]: T[P] | null; \/\/ T\u00fcm \u00f6zellikleri null olabilecek hale getirir\n};\n\ntype UserWithNullableProps = NullableProperties<UserProfile>;\n\/\/ UserWithNullableProps: { name: string | null; email: string | null; age: number | null; }<\/code><\/pre>\n<p>Mapped Types, \u00f6zellikle <code>Pick<\/code>, <code>Omit<\/code>, <code>Record<\/code> gibi TypeScript&#8217;in yerle\u015fik utility tiplerinin arkas\u0131ndaki mekanizmad\u0131r ve g\u00fc\u00e7l\u00fc tip d\u00f6n\u00fc\u015f\u00fcmlerine olanak tan\u0131r.<\/p>\n<h3>Template Literal Types ile Generics<\/h3>\n<p>TypeScript 4.1 ile tan\u0131t\u0131lan Template Literal Types, string literal tipleri \u00fczerinde dinamik manip\u00fclasyonlar yapmam\u0131z\u0131 sa\u011flar. Generics ile birle\u015fti\u011finde, string tabanl\u0131 tipleri programatik olarak olu\u015fturabiliriz.<\/p>\n<pre><code class=\"language-typescript\">\/\/ Capitalize<T> utility tipinin \u00e7al\u0131\u015fma mant\u0131\u011f\u0131na benzer\ntype MyCapitalize<S extends string> =\n  S extends <code>${infer FirstLetter}${infer Rest}<\/code>\n    ? <code>${Uppercase<FirstLetter>}${Rest}<\/code>\n    : S;\n\ntype GreetMessage = MyCapitalize<\"hello world\">; \/\/ \"Hello world\"\n\n\/\/ Kendi \u00f6rne\u011fimiz: Bir string'e \u00f6nek ekleme\ntype AddPrefix<T extends string, Prefix extends string> = <code>${Prefix}${T}<\/code>;\n\ntype EventName = AddPrefix<\"click\", \"on\">; \/\/ \"onclick\"\ntype ApiEndpoint = AddPrefix<\"users\", \"\/api\/\">; \/\/ \"\/api\/users\"<\/code><\/pre>\n<p>Bu \u00f6zellik, \u00f6zellikle API endpoint&#8217;leri, event isimleri veya CSS s\u0131n\u0131f isimleri gibi string tabanl\u0131 tipleri g\u00fcvenli bir \u015fekilde olu\u015fturmak i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<h2>Generics Kullan\u0131m\u0131nda Dikkat Edilmesi Gerekenler ve En \u0130yi Pratikler<\/h2>\n<p>Generics g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r, ancak do\u011fru kullan\u0131lmad\u0131\u011f\u0131nda kodun karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 art\u0131rabilir. \u0130\u015fte Generics kullan\u0131rken dikkat edilmesi gerekenler ve en iyi pratikler:<\/p>\n<p>1.  <strong>Anlaml\u0131 Tip De\u011fi\u015fkeni \u0130simleri Kullan\u0131n:<\/strong><br \/>\n    *   Tek harfli isimler (T, U, V, K, P) genellikle basit durumlarda (\u00f6rne\u011fin <code>identity<T><\/code>) veya standart olarak kabul edilmi\u015f durumlarda (\u00f6rne\u011fin <code>K<\/code> i\u00e7in <code>Key<\/code>, <code>V<\/code> i\u00e7in <code>Value<\/code>) kullan\u0131l\u0131r.<br \/>\n    *   Daha karma\u015f\u0131k senaryolarda veya birden fazla generic tip de\u011fi\u015fkeni oldu\u011funda, daha a\u00e7\u0131klay\u0131c\u0131 isimler (\u00f6rne\u011fin <code>TElement<\/code>, <code>TValue<\/code>, <code>TProps<\/code>) kullanmak okunabilirli\u011fi art\u0131r\u0131r.<\/p>\n<p>2.  <strong>Gereksiz Generic Kullan\u0131m\u0131ndan Ka\u00e7\u0131n\u0131n:<\/strong><br \/>\n    *   Her zaman generic kullanmak zorunda de\u011filsiniz. E\u011fer bir fonksiyon veya s\u0131n\u0131f sadece belirli bir tip ile \u00e7al\u0131\u015f\u0131yorsa veya <code>any<\/code> veya union tipler (<code>string | number<\/code>) yeterli geliyorsa, Generics kullanmak kodu gereksiz yere karma\u015f\u0131k hale getirebilir.<br \/>\n    *   \u00d6rne\u011fin, sadece <code>string<\/code> veya <code>number<\/code> ile \u00e7al\u0131\u015fan bir fonksiyon i\u00e7in generic kullanmak yerine do\u011frudan bu tipleri belirtmek daha iyidir.<\/p>\n<p>3.  <strong>K\u0131s\u0131tlamalar\u0131 Ak\u0131ll\u0131ca Kullan\u0131n:<\/strong><br \/>\n    *   K\u0131s\u0131tlamalar (<code>extends<\/code>), generic tiplerin alabilece\u011fi de\u011ferleri daraltarak tip g\u00fcvenli\u011fini art\u0131r\u0131r. Ancak \u00e7ok fazla k\u0131s\u0131tlama, bile\u015fenin esnekli\u011fini azaltabilir.<br \/>\n    *   Sadece ihtiyac\u0131n\u0131z olan k\u0131s\u0131tlamalar\u0131 ekleyin. \u00d6rne\u011fin, bir objenin sadece <code>id<\/code> \u00f6zelli\u011fine ihtiyac\u0131n\u0131z varsa, t\u00fcm <code>User<\/code> aray\u00fcz\u00fcn\u00fc k\u0131s\u0131tlamak yerine sadece <code>HasId<\/code> aray\u00fcz\u00fcn\u00fc k\u0131s\u0131tlay\u0131n.<\/p>\n<p>4.  <strong>Hata Mesajlar\u0131n\u0131 Anlay\u0131n:<\/strong><br \/>\n    *   Generic tiplerle \u00e7al\u0131\u015f\u0131rken TypeScript&#8217;in hata mesajlar\u0131 bazen kafa kar\u0131\u015ft\u0131r\u0131c\u0131 olabilir. \u00d6zellikle k\u0131s\u0131tlamalarla ilgili hatalarda, hangi tipin hangi k\u0131s\u0131tlamay\u0131 ihlal etti\u011fini anlamaya \u00e7al\u0131\u015f\u0131n.<br \/>\n    *   Hata mesajlar\u0131n\u0131 dikkatlice okuyarak, generic tip de\u011fi\u015fkenlerinin neye d\u00f6n\u00fc\u015ft\u00fcr\u00fcld\u00fc\u011f\u00fcn\u00fc ve neden bir tip uyumsuzlu\u011fu oldu\u011funu anlamak, sorunu \u00e7\u00f6zmenize yard\u0131mc\u0131 olur.<\/p>\n<p>5.  <strong>Generics ve Overloading:<\/strong><br \/>\n    *   Bazen bir fonksiyonu generic yapmak yerine fonksiyon overloading (a\u015f\u0131r\u0131 y\u00fckleme) kullanmak daha okunakl\u0131 olabilir. \u00d6zellikle fonksiyonun farkl\u0131 arg\u00fcman tipleri i\u00e7in tamamen farkl\u0131 davran\u0131\u015flar sergilemesi gerekiyorsa, overloading tercih edilebilir.<br \/>\n    *   Ancak, ayn\u0131 mant\u0131\u011f\u0131 farkl\u0131 tiplerle uyguluyorsan\u0131z ve sadece tip g\u00fcvenli\u011fi i\u00e7in farkl\u0131 imzalar tan\u0131mlaman\u0131z gerekiyorsa, Generics genellikle daha iyi bir \u00e7\u00f6z\u00fcmd\u00fcr.<\/p>\n<p>6.  <strong>Performans Etkisi (Derleme Zaman\u0131):<\/strong><br \/>\n    *   Generics, yaln\u0131zca derleme zaman\u0131nda tip kontrol\u00fc i\u00e7in kullan\u0131l\u0131r. JavaScript&#8217;e derlendi\u011finde, generic tip bilgileri tamamen kald\u0131r\u0131l\u0131r. Bu, \u00e7al\u0131\u015fma zaman\u0131 performans\u0131na herhangi bir etkisi olmad\u0131\u011f\u0131 anlam\u0131na gelir.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>TypeScript Generics, statik tiplemenin g\u00fcc\u00fcn\u00fc esneklikle birle\u015ftiren kritik bir \u00f6zelliktir. Bu makalede, Generics&#8217;in temel kavramlar\u0131ndan ba\u015flayarak, fonksiyonlar, aray\u00fczler, tip alias&#8217;lar\u0131 ve s\u0131n\u0131flar gibi farkl\u0131 kullan\u0131m alanlar\u0131n\u0131 detayl\u0131 bir \u015fekilde inceledik. Ayr\u0131ca, generic k\u0131s\u0131tlamalar, <code>keyof<\/code>, <code>typeof<\/code>, ko\u015fullu tipler, mapped tipler ve template literal tipleri gibi ileri seviye konulara de\u011finerek, Generics&#8217;in ne kadar kapsaml\u0131 ve g\u00fc\u00e7l\u00fc bir ara\u00e7 oldu\u011funu g\u00f6sterdik.<\/p>\n<p>Generics kullanarak, kod tekrar\u0131n\u0131 azalt\u0131r, daha tip g\u00fcvenli ve yeniden kullan\u0131labilir bile\u015fenler olu\u015ftururuz. Bu, b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalar\u0131n geli\u015ftirilmesinde hatalar\u0131 erken yakalamam\u0131z\u0131 sa\u011flar ve geli\u015ftirme s\u00fcrecini daha verimli hale getirir. \u0130yi tasarlanm\u0131\u015f generic bile\u015fenler, kod taban\u0131n\u0131z\u0131n bak\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r ve gelecekteki de\u011fi\u015fikliklere kar\u015f\u0131 daha diren\u00e7li olmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>Unutmay\u0131n, Generics&#8217;i etkin bir \u015fekilde kullanmak pratik gerektirir. TypeScript projelerinizde Generics&#8217;i denemekten \u00e7ekinmeyin, farkl\u0131 senaryolarda nas\u0131l uygulayabilece\u011finizi ke\u015ffedin. Bu derinlemesine rehberin, TypeScript Generics&#8217;i anlaman\u0131za ve projelerinizde ustaca kullanman\u0131za yard\u0131mc\u0131 olaca\u011f\u0131n\u0131 umuyoruz. Generics ile TypeScript&#8217;in sundu\u011fu t\u00fcm g\u00fcc\u00fc a\u00e7\u0131\u011fa \u00e7\u0131kar\u0131n ve daha sa\u011flam, \u00f6l\u00e7eklenebilir uygulamalar geli\u015ftirin.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber\nGiri\u015f\nModern web uygulamalar\u0131 geli\u015ftirirken, kodun okunabilirli\u011fi, bak\u0131m\u0131 ve \u00f6ze","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-33946","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>TypeScript&#039;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TypeScript&#039;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber\" \/>\n<meta property=\"og:description\" content=\"TypeScript&#039;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber Giri\u015f Modern web uygulamalar\u0131 geli\u015ftirirken, kodun okunabilirli\u011fi, bak\u0131m\u0131 ve \u00f6ze\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-09T02:40:48+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber\",\"datePublished\":\"2025-11-09T02:40:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\"},\"wordCount\":2397,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\",\"name\":\"TypeScript'te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-09T02:40:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"TypeScript'te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/","og_locale":"tr_TR","og_type":"article","og_title":"TypeScript'te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber","og_description":"TypeScript'te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber Giri\u015f Modern web uygulamalar\u0131 geli\u015ftirirken, kodun okunabilirli\u011fi, bak\u0131m\u0131 ve \u00f6ze","og_url":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-09T02:40:48+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"18 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber","datePublished":"2025-11-09T02:40:48+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/"},"wordCount":2397,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/","url":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/","name":"TypeScript'te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-09T02:40:48+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/typescriptte-generics-kullanimi-derinlemesine-bir-rehber\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"TypeScript&#8217;te Generics Kullan\u0131m\u0131: Derinlemesine Bir Rehber"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33946","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=33946"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33946\/revisions"}],"predecessor-version":[{"id":33947,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33946\/revisions\/33947"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=33946"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=33946"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=33946"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}