Skip to content

Instantly share code, notes, and snippets.

@ScriptRaccoon
Last active June 30, 2023 19:51
Show Gist options
  • Select an option

  • Save ScriptRaccoon/c5667b85c5f4b9c7255b4a1daddc19ad to your computer and use it in GitHub Desktop.

Select an option

Save ScriptRaccoon/c5667b85c5f4b9c7255b4a1daddc19ad to your computer and use it in GitHub Desktop.
Introduction to Generics
// 1. Example: get last element of any array
function last_element<X>(arr: Array<X>): X {
return arr[arr.length - 1];
}
// 2. Example: get id of an object which has an id
type person = {
name: string;
age: number;
id: string;
};
type city = {
name: string;
location: string;
id: string;
};
function get_id<T extends { id: string }>(object: T): string {
return object.id;
}
// 3. Example: add an id to an object
function add_id<T>(obj: T): T & { id: string } {
const id = crypto.randomUUID();
return { ...obj, id };
}
// 4. Example: unify database entries
type database_entry<X> = {
id: string;
created: Date;
updated: Date;
} & X;
type user = database_entry<{
name: string;
age: number;
role: "admin" | "editor" | "guest";
}>;
type post = database_entry<{
title: string;
text: string;
likes: number;
}>;
// 5. Example: utilities
function is_equal<X>(a: X, b: X) {
return a === b;
}
function identity<X>(a: X): X {
return a;
}
function compose<X, Y, Z>(
f: (x: X) => Y,
g: (y: Y) => Z
): (x: X) => Z {
return function (x: X): Z {
const y = f(x);
const z = g(y);
return z;
};
}
// 6. Example: Promises
async function get_answer(): Promise<number> {
return 42;
}
async function get_user(): Promise<user> {
return {
id: "u591y",
created: new Date("2023-04-02"),
updated: new Date("2023-05-26"),
name: "John Doe",
age: 21,
role: "editor",
};
}
// 7. Example: cache decorator function
async function expensive_api_call(): Promise<string> {
return "This is the result";
}
function cache_function<T>(fun: () => T, duration: number): () => T {
let cache: T;
let saved: Date;
return function () {
const now = new Date();
if (cache && now.getTime() - saved.getTime() < duration) {
console.log("read from cache ๐Ÿ˜Ž");
return cache;
} else {
console.log("need to compute ๐Ÿ™„");
const result = fun();
cache = result;
saved = new Date();
return result;
}
};
}
const cached_api_call = cache_function(expensive_api_call, 10000);
setInterval(async () => {
await cached_api_call();
}, 1000);
// 8. Example: Generic classes
// See the Server class in
// https://github.com/ScriptRaccoon/svelte-chat-app/blob/main/server.ts
// 9. Example: Function evaluation and currying
function evaluate<X, Y>(fun: (x: X) => Y, x: X): Y {
return fun(x);
}
function curry<X, Y, Z>(
fun: ([x, y]: [X, Y]) => Z
): (x: X) => (y: Y) => Z {
return (x: X) => (y: Y) => fun([x, y]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment