hyperscript-helpers
hyperscript-helpers copied to clipboard
Constrain typescript definitions
Provides better type safetly by forwarding the types of the hyperscript implementation to the helper.
The types put some constraints in place that the actual code doesn't:
- The generated helpers have 3 arguments (this is already the case in the current typings)
- argument "attributes" comes before "children"
- attributes and children are constrained (but sensibly so I would say)
2 and 3 restrict both the hyperscript implementation and the generated helpers
I tried to get rid of these assumptions by "forwarding" the types entirely from the hyperscript implementation. Unfortunately I'm either not smart enough to make that work or it's not possible.
Below is how far I got using that approach. It works in a few cases but R1 and R2 are too restricted somehow. When I add R3 things get more messed up.
/**
* The minimal featureset the hyperscript implementation should support
*/
declare interface HyperScriptFn<Element, Tag, R1, R2> {
(tag: Tag, r1?: R1, r2?: R2): Element;
}
/**
* The actual hyperscript-helper function
* The purpose of hyperscript-helpers is so you can use this function
*/
declare interface HyperScriptHelperFn<
H extends HyperScriptFn<any, any, any, any>,
Element = H extends HyperScriptFn<infer Element, any, any, any> ? Element : never,
R1 = H extends HyperScriptFn<any, any, infer R1, any> ? R1 : never,
R2 = H extends HyperScriptFn<any, any, any, infer R2> ? R2 : never
> {
(selector: string, r1?: R1, r2?: R2): Element;
(r1?: R1, r2?: R2): Element;
}
/**
* Map of the actual helper functions generated by hh()
*/
declare type HyperScriptHelpers<H extends HyperScriptFn<any, any, any, any>> = {
[key in (keyof HTMLElementTagNameMap | 'svg')]: HyperScriptHelperFn<H>;
}
export default function hh<
H extends HyperScriptFn<any, any, any, any>,
>(h: H): HyperScriptHelpers<H>;
I gave it another shot to get rid of the overly strict requirements on the hyperscript implementation.
And it looks I succeeded!
Unfortunately I seem to run into the typescript issue below which makes it so that the hyperscript implementation can't have any overloads.
https://github.com/Microsoft/TypeScript/issues/13570
This is a deal-breaker because the implementations need the overloads for correctness.
So looks like the current commit is as good as it gets unfortunately.
Support for this would be great