Typescript demetlerine daha yakından bir bakış
Hızlı bir hatırlatma olarak, en temel tanımında bir demet, yalnızca birden çok parçadan oluşan bir veri yapısıdır. Typescript gibi programlama dillerinde tanımlama grupları kullanma kapsamında, verilerin en yaygın olarak sıralandığına dikkat etmek de önemlidir.
Basit bir örnek, tanımlama gruplarının TypeScript'te nasıl tanımlandığını gösterir.
// This tuple is defined as a set
// of two numbers.
const scores: [number, number] = [1, 2];
// For comparison, this tuple consists
// of three elements, each of a different
// type. Not that the ordered nature of
// tuples in TS becomes very clear here.
const result: [string, number, boolean] = ["id", 101, false];
// And as a "nice-to-know", you can even
// provide lables for the tuple elements.
// This doesn't have any effect on the typesystem
// itself and only (may) improve documentation.
const output: [id: number, name: string] = [101, "Tom"];
İsteğe bağlı elemanlara sahip demetler
Typescript zamanla daha iyi hale geldikçe, tuple uygulaması da arttı. Yalnızca zorunlu olması gereken öğeleri tanımlamanız gerekmez. Artık öğeleri isteğe bağlı olarak da yazabilirsiniz. Bilmiyorsanız, TypeScript, öğeleri isteğe bağlı olarak tanımlamak için genel bir sembol olarak soru işaretini kullanır; bu, çalışma zamanında mevcut olabilecekleri, ancak zorunlu olmadıkları anlamına gelir.
Başka bir örnek bununla ne demek istediğimi gösteriyor.
// Similar to our previous example, but in this
// case the the tuple's last element doesn't have
// to be provided (or can be undefined at runtime).
type Tuple = [id: number, name?: string];
const a: Tuple = [101];
const b: Tuple = [42, "Tom"];
TypeScript demetlerindeki dinlenme elemanları
Dinlenme öğeleriyle, belirli bir türün demetinde takip eden tüm öğeleri işaretleyen çok güçlü bir türünüz vardır. Diyelim ki iki elemanlı bir demetiniz var ve ikincisi bir dinlenme elemanı olarak tanımlandı, daha sonra bu demet değişkenine çalışma zamanında 2 + n eleman sağlayabilirsiniz.
Tanımı daraltmak gerekirse, yakın zamana kadar böyle bir öğeye yalnızca bir demetin sonunda izin veriliyordu. Bu, dinlenme türünün çalışma zamanında herhangi bir sayıda öğe sağlamanıza izin verdiği için mantıklıdır, ancak daha sonra dinlenme öğesi ile bir başka yazılan öğe arasında ayrım yapmak için işleri çok karmaşık hale getirir.
// This example might be a tuple type
// for a CLI similar to Node.js. The first
// two elements are system-internal.
//
// Starting from the 3rd element, a user can
// provide as much arguments as desired, yet
// we can still cleanly handle it with TS. Nice!
let input: [number, boolean, ...string[]];
// Just to show that we really can provide any
// number of rest elements, including 0.
e = [0, false, "max-cache", "1024", "debug", "false"];
e = [0, false];
e = [0, false, "verbose"];
Tuple türlerinde lider veya orta dinlenme öğesi
Tuple'lar için dinlenme öğesini geliştirerek, TypeScript 4.2'nin piyasaya sürülmesinden bu yana daha da karmaşık uygulamalar oluşturabilirsiniz. Ve burada özür dilemeliyim: sadece birkaç cümle erken, sadece sonuncusu olarak bir dinlenme öğesini kullanmanın nasıl zorunlu olduğunu yazdım. Typescript 4.2'den beri bu kısıtlama artık doğru değil, çünkü artık kalan öğeleri bir demet içinde hemen hemen her yere yerleştirebilirsiniz.
Ancak yalnızca birkaç kısıtlamayla Typescript artık gelişmiş tanımlama grupları için çok güzel bir sözdizimi sağlıyor. Dinlenme öğeleri, aşağıdaki iki kurala uyduğu sürece bir demet içinde herhangi bir yerde olabilir.
- isteğe bağlı bir öğe tarafından takip edilmez
- ilkini takip eden başka bir dinlenme öğesi yok
Çok fazla teori konuşmadan önce, bir örnek görelim.
// And here comes the fancy part: rest elements
// *not only* at the end of a tuple.
//
// Note: this example is taken directly from the
// TS documentation. For more details, check out the
// links in the addendum.
let foo: [...string[], number];
foo = [123];
foo = ["hello", 123];
foo = ["hello!", "hello!", "hello!", 123];
let bar: [boolean, ...string[], boolean];
bar = [true, false];
bar = [true, "some text", false];
bar = [true, "some", "separated", "text", false];
// And here's an example that shows how the
// type system would catch your errors:
interface Clown { /*...*/ }
interface Joker { /*...*/ }
let StealersWheel: [...Clown[], "me", ...Joker[]];
// ~~~~~~~~~~ Error!
// A rest element cannot follow another rest element.
let StringsAndMaybeBoolean: [...string[], boolean?];
// ~~~~~~~~ Error!
// An optional element cannot follow a rest element.
Bu makalenin geri kalan öğesi
Typescript'teki demetler hakkındaki bu küçük kılavuzun sonunda, temel uygulamaya bir göz attık ve ardından Typescript'in söz konusu demetler söz konusu olduğunda çok esnek bir tip sistemine nasıl izin verdiğini görmek için bazı daha gelişmiş örnekleri inceledik. Umarım makaleyi beğenmişsinizdir ve daha fazlasını öğrenmek istiyorsanız, aşağıda önerilen diğer gönderilere göz atın.