import type { DefaultRegistry, Methods, Registry } from "../registry"; import type { shim } from "./mixin"; export type Base = T extends { [shim]: { value: infer U } } ? { readonly value: U } : { readonly value: T; }; export type Fluent< T, Reg extends Registry = DefaultRegistry, > = Base & Methods extends infer U ? U & Pick< { /** * Immediate casts and conversions to other types. */ to: unknown; [K: PropertyKey]: unknown; }, keyof U > : never; export function makeFluent( registry: Reg, ) { const fluent = (value: T) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const f = { value } as unknown as Fluent; for (const mixin of registry) { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion mixin.fn(value, f, fluent as (value: unknown) => never); } return f; }; return fluent; }