/* ------- ⭐️ Generic type alias -------- */
// ⭐️ generic types
type Optional<T> = T | null;
type OneOrMany<T> = T | T[];
type OptioanlOneOrMany<T> = Optional<OneOrMany<T>>; // T | T[] | null
// ⭐️ concrete type
type OptionalOneOrManyStrings = OptioanlOneOrMany<string>;
// string | string[] | null
type Box<T> = { contents: T; };
/* ------- ⭐️ Generic interface -------- */
interface Box<T> { // `T`: type parameter
contents: T;
}
let box: Box<string>; // `string`: type argument
/* ------- ⭐️ Generic functions -------- */
function setContents<T>(box: Box<T>, contents: T) {
box.contents = contents;
}