Skip to content

Instantly share code, notes, and snippets.

@saiashirwad
Last active January 9, 2025 10:30
Show Gist options
  • Save saiashirwad/6c6523f08127388ba39272492f3178b6 to your computer and use it in GitHub Desktop.
Save saiashirwad/6c6523f08127388ba39272492f3178b6 to your computer and use it in GitHub Desktop.
minimal hkt in ts
export type Fn = (...x: never[]) => unknown
export declare const _: unique symbol
export type _ = typeof _
export declare abstract class Kind<F extends Fn = Fn> {
abstract readonly [_]: unknown
f: F
}
export type Input<F extends Kind> = F extends { f: (x: infer X) => any }
? X
: unknown
export type pipe<T extends Kind[], X> = T extends [
infer Head extends Kind,
...infer Tail extends Kind[],
]
? [X] extends [never]
? never
: pipe<Tail, apply<Head, cast<X, Input<Head>>>>
: X
export type cast<T, U> = T extends U ? T : U
export type apply<F extends Kind, X extends Input<F>> = ReturnType<
(F & {
readonly [_]: X
})["f"]
>
// Example
interface CapitalizeKind extends Kind {
f(x: cast<this[_], Record<string, unknown>>): {
[key in keyof typeof x as Capitalize<key & string>]: (typeof x)[key]
}
}
interface OptionalKind extends Kind {
f(x: cast<this[_], Record<string, unknown>>): {
[key in keyof typeof x]?: (typeof x)[key]
}
}
export interface First extends Kind {
f(x: cast<this[_], unknown[]>): typeof x extends [] ? never : (typeof x)[0]
}
type result = pipe<[OptionalKind, CapitalizeKind], { hi: "there"; age: 5 }>
type lha = apply<OptionalKind, { hi: "there" }>
type asdf = apply<First, [1, 2, 3]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment