Created
February 24, 2024 00:09
-
-
Save joelburton/1ce686b0439d32cc3d2b17c30240a038 to your computer and use it in GitHub Desktop.
Generics in TS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols | |
// TypeScript Generics 🧐 | |
function choice(items) { | |
const item = items[Math.floor(Math.random() * items.length)]; | |
console.log({ item }); | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
const rando1 = choice([1, 2, 3]); | |
const rando2 = choice(["a", "b", "c"]); | |
function choice_num(items: number[]): number { | |
const item = items[Math.floor(Math.random() * items.length)]; | |
console.log({ item }); | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
const n = choice_num([1, 2, 3]); | |
function choice_str(items: string[]): string { | |
const item = items[Math.floor(Math.random() * items.length)]; | |
console.log({ item }); | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
const s = choice_str(["a", "b", "c"]); | |
function choice_any(items: any[]): any { | |
const item = items[Math.floor(Math.random() * items.length)]; | |
console.log({ item }); | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
const a = choice_any([1, 2, 3]); | |
const b = choice_any(["a", "b", "c"]); | |
function choice_union(items: (string | number)[]): (string | number) { | |
const item = items[Math.floor(Math.random() * items.length)]; | |
console.log({ item }); | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
const c = choice_union([1, 2, 3]); | |
const d = choice_union(["a", "b", "c"]); | |
{ | |
const c_num = choice_union([1, 2, 3]) as number; | |
} | |
function choice_generic<T>(items: T[]): T { | |
const item = items[Math.floor(Math.random() * items.length)]; | |
console.log({ item }); | |
return items[Math.floor(Math.random() * items.length)]; | |
} | |
const e = choice_generic([1, 2, 3]); | |
const f = choice_generic(["a", "b", "c"]); | |
{ | |
// explicit type not needed, but is ok to do: | |
const g = choice_generic<string>(["a", "b", "c"]); | |
} | |
class CartItem { | |
title: string; | |
price: number; | |
constructor(title: string, price: number) { | |
this.title = title; | |
this.price = price; | |
} | |
} | |
class Book extends CartItem { } | |
class Toy extends CartItem { } | |
class Cart<T> { | |
items: T[]; | |
constructor(items: T[] = []) { this.items = items; } | |
count(): number { return this.items.length; } | |
} | |
const bookCart = new Cart([ | |
new Book("Hamlet", 5), | |
new Book("The Bell Jar", 10) | |
]); | |
const count1 = bookCart.count(); | |
{ | |
const bookCart_explicit = new Cart<Book>(); | |
bookCart_explicit.items.push(new Book("Regeneration", 12.50)); | |
const count2 = bookCart_explicit.count(); | |
} | |
class CartWithTotal<T> { | |
items: T[]; | |
constructor(items: T[] = []) { this.items = items; } | |
count(): number { return this.items.length; } | |
totalCost(): number { | |
return this.items.reduce((prev, cur) => prev + cur.price, 0); | |
} | |
} | |
const numCart = new CartWithTotal([1, 2, 3, 4]); | |
const numCount = numCart.count(); | |
const numTotal = numCart.totalCost(); // ut oh: "(cur as ShopItem).price" | |
class SafeCart<T extends CartItem> { | |
items: T[]; | |
constructor(items: T[]) { this.items = items; } | |
count(): number { return this.items.length; } | |
totalCost(): number { | |
return this.items.reduce((prev, cur) => prev + cur.price, 0); | |
} | |
} | |
const ss = new SafeCart([new Book("Regeneration", 12.50)]); | |
const ns = new SafeCart([1, 2, 3]); // ERR | |
class AlsoSafeCart<T extends {price: number}> { | |
items: T[]; | |
constructor(items: T[]) { this.items = items; } | |
count(): number { return this.items.length; } | |
totalCost(): number { | |
return this.items.reduce((prev, cur) => prev + cur.price, 0); | |
} | |
} | |
const catCart = new AlsoSafeCart([ | |
{title: "Ezra, Viscount of Derp", price: 11.23, color: "creamsicle"}, | |
{title: "Auden, Marquis of Meow", price: 99.95, color: "taupe-grey"}, | |
]); | |
const appleCart = new AlsoSafeCart([ // ERR! | |
{title: "Fuji", color: "red"}, | |
{title: "Gala", color: "red"}, | |
]); | |
// Thank you for coming to my generic talk! 🐧 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment