Last active
January 9, 2025 10:30
-
-
Save saiashirwad/6c6523f08127388ba39272492f3178b6 to your computer and use it in GitHub Desktop.
minimal hkt in ts
This file contains hidden or 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
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