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