evilsoft / crocks

A collection of well known Algebraic Data Types for your utter enjoyment.
https://crocks.dev
ISC License
1.59k stars 102 forks source link

Proposal to Add TS typings via JSDoc #446

Closed bennypowers closed 4 years ago

bennypowers commented 4 years ago

I'd like to reopen the discussion about TS typings. TS 3.7.0 allows generating declaration files from JSDoc comments, so now is a good time to reconsider our position.

The goal of this proposal is to provide IDE niceties like autocomplete and docs-on-hover. Turning crocks into a TypeScript project is explicitly an anti-goal.

Proposal

I propose that we adopt JSDoc in crocks, by converting the inline type sigs in all files to block comments, retaining the HM types as descriptions, and adding JSDoc types, as well.

so that

// hasProp :: (String | Integer) -> a -> Boolean

becomes

/**
 * hasProp :: (String | Integer) -> a -> Boolean
 * @type {((x: string|number) => (a: any) => boolean)|((x: string|number, x: any) => boolean)}
 */

This would allow us to use the new declaration with allowJS feature in TS 3.7.0 to generate declaration files like:

declare module 'crocks/predicates/hasProp' {
    /** hasProp :: (String | Integer) -> a -> Boolean */
    export default function hasProp(k: string): PredicateFunction;
    /** hasProp :: (String | Integer) -> a -> Boolean */
    export default function hasProp(k: string, x: any): Boolean;
}

These would either be built into the package in the prepare hook, or published under the @types/crocks npm package

The previous proposal was rejected in part because crocks' dynamism is out of scope of TS' capabilities. I propose here that for exports which are too dynamic or complex for TS's typing system, we omit JSDoc types but still convert comments to block style. For those exports which are not congruent with TS' current abilities, converting to block-style comments would at the least bring the HM type sigs to the user's attention while hovering over the exported functions in their IDE.

Since this is about documentation, not code correctness or compatibility, I think we can do this piecemeal, even explicitly setting out to not completely document all exports, and it will still provide benefit to some users.

consider for example a user developing a typescript (or js-typed JS project) in a ts-language-server IDE like VSCode or Atom, who primarily uses helpers and pointfree functions in their project, while avoiding using the ADTs. These type annotations would still provide tremendous programming-time value.

Screen Shot 2019-10-24 at 9 46 28

Extensions and Alternatives

This proposal could be extended to leverage hm-doc and/or hm-def to generate the JSDoc annotations, but this might be out of scope.

Additionally, and apropos recent discussions about docs on crocks.dev, we could decide to fully leverage JSDoc, so that all docs for all exports are kept in the exported files themselves, rather than in a separate docs root-level directory. We would generate the markdown for the docs site directly from source files, which would cut down on maintenance and reduce the chance for docs/code inconsistencies.

This proposal also complements our work towards es modules, which the ts-language server already statically analyses.

dalefrancis88 commented 4 years ago

I think this may be something we need to seriously consider. As I currently look to find a good documentation replacement JSDoc always keeps popping up as the best alternative.

@bennypowers I love all the extra detail in here. Maybe as an option to help decide on difficulty/scope of this we could outline some of the more difficult areas of the code to add this documentation too?

evilsoft commented 4 years ago

I like the idea for IDE niceties. Do not know about the JSDocs route, but we are providing siggiys in the source anyway, why not go the extra mile. I am 💯 for this. As far as the docs go, I am not as stoked about, but can be swayed with some good arguments. Any idea on how we would represent the Types themselves? I can see this as a BIG win for functions, but for things like say map where we take all Functors, how would represent that?

Will also need to think about what it will cost to "maintain" these typings (not a downer, but good to know what we will be getting into to). But I totes think that anything we can do to help the dev is 👍 in my 📖

bennypowers commented 4 years ago

Closing in favour of #286