Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stronger registerFunction TS types by inferring types from signature, and a road to a language service (PR coming!) #689

Open
adamscybot opened this issue Apr 27, 2024 · 0 comments

Comments

@adamscybot
Copy link
Contributor

adamscybot commented Apr 27, 2024

First a little context, I have a PR I've been chipping away at that's 95% done. I have completed this work as part of another package I am working on that creates a "plugin" wrapper around JSONata, but it struck me there's no reason this particular part can't be in the core. The change is exclusively only to the TS types. I will raise it hopefully over the next week, I just need to move it from my WIP package. You can see the impl thus far here. I've put in a fair amount of effort in clearing all the edge cases. I'm first creating this issue to set the goals and invite discussion, and hopefully get some indication from the maintainers that they think this would be good and approval-permitting, could be merged 😊.

When using TS with JSonata It's a little tiresome and error-prone to have to manually define the types of a function provided to registerFunction when they are already expressed within the signature string. For example:

expression.registerFunction(
  "<s-ns?:s>",
  (
    arg1: string | undefined,
    arg2: number | undefined,
    arg3: string | undefined,
  ) => {
    // stuff
  },
);

Wouldn't it be nice if TS just knew from the signature those were the types? Well, now we can! Via TS Template Literal Types.

I propose that via modification to the TS declarations of the package, we could implement a TS based signature string parser that can automatically infer the types of the args. Including complex cases like unions, subtypes, nested subtypes. and even taking into account modifiers.

Below screenshots show proposed ParseSignature type alias being used directly, but it would be used automatically under the hood for registerFunction in the final PR and automatically read the passed signature string.

image

It could also detect bad signature at compile time.

image

This would:

  1. Give stronger guarantees for typescript users, and nice IDE support for registerFunction.
  2. Find erroneous or problematic signatures.
  3. Open the door to a possible language service in something like VSCode for JSonata. It seems like a lot of code just to make registerFunction nice (but that's valuable too; and its only type declarations without runtime change). But being able to do this makes a basic language service support much more achievable. Since the function registry (and associated signatures) could be used to check usage and provide errors in the IDE in actual queries! This PR wont cover it, but its a step there.
  4. No idea if this is something that the maintainers care about, but if changing the actual core impl of JSONata to TS was on the cards this is the most annoying hurdle gone, if wanting to avoid breaking changes and have good type safety.
@adamscybot adamscybot changed the title Stronger registerFunction TS types by inferring types from signature (PR coming!) Stronger registerFunction TS types by inferring types from signature, and a road to a language service (PR coming!) Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant