KartikTalwar / gmail.js

Gmail JavaScript API
MIT License
3.74k stars 455 forks source link

Create generic concept for GmailBindAction to allow extension #700

Closed cancan101 closed 1 year ago

josteink commented 2 years ago

The current solution looks good to me. To be honest, I'd probably only apply a string | GmailBindAction and call it day, but this is even better.

As for the code, couldn't/shouldn't the generic parameter rather be declared on the method instead of the class, since it only applies to that method?

Otherwise PR looks good to me.

cancan101 commented 2 years ago

As for the code, couldn't/shouldn't the generic parameter rather be declared on the method instead of the class, since it only applies to that method?

It applies to a few methods. I just changed one for example but technically on, after, etc can be changed too. Also register can be made stricter / more correct: https://github.com/KartikTalwar/gmail.js/pull/700#discussion_r886143560 but that would be a breaking change.

josteink commented 2 years ago

Register could be changed to:

register(action: T, args: string | StringDict): void;

but that would be a breaking change

I don't think that would be correct, would it?

StringDict would only accept (non-key) values of type string, but handler needs to be a function, right?

cancan101 commented 2 years ago

My point there as on the change of the type of action, i.e:

register(action: string, args: string | StringDict): void;

to

register(action: T, args: string | StringDict): void;

the type of args was recently changed in another PR of mine

josteink commented 2 years ago

I'll admit that right now, this change seems too abstract for min to fully consider the scope of, without having some concept code demonstrating how that would be broken by this change.

Also: Setting a generic argument on the main Gmail-class itself, for an argument which is used 2 levels down in the API hierarchy also feels a bit icky. I'm not sure I like it :smile:

Could you provide 2 examples?

Then based on those, it might be easier to come up with a decision about which case should be rated most important to ensure works.

cancan101 commented 2 years ago

At present this code does not work:

const GmailFactory = require('gmail-js');
const gmail = new GmailFactory.Gmail(jQuery) as Gmail;

gmail.observe.register('popout_thread', popoutThreadConfig);

// this is an issue as on_dom expects a GmailBindAction
gmail.observe.on_dom(
  'popout_thread',
  ...
)

if you just change on_dom to take a string then you weaken the type safety that exists in cases w/o a custom dom event.

josteink commented 2 years ago

If the TS compiler can infer T for the main Gmails-class, that would be a nice feature to working.

If not, it’s definitely reduces the ergonomics for pretty much all other use-cases, and I’m against that.

cancan101 commented 2 years ago

well the idea is to provide a default for T so in 99% of use cases the users can use as is. Only in the case of wanting to register custom dom events does the user need to specify the typing.

josteink commented 2 years ago

I’d be OK with that.

josteink commented 2 years ago

Just checking in. Did you get anywhere with this one? :)

cancan101 commented 2 years ago

I think good for review. Only question is whether it makes sense to tighten the typing on register per my comment: https://github.com/KartikTalwar/gmail.js/pull/700/files#r886143560

josteink commented 2 years ago

Back from vacation now. Will try to take a look at this when I have time.

josteink commented 2 years ago

Apart from some minor nitpicks about return-types, this looks OK to me.

I won't need it, but if it doesn't otherwise interfere with "normal" GMailJS usage, I don't see the harm either.

josteink commented 2 years ago

Ready when you are 🙂

josteink commented 1 year ago

Any news on this one? It seems like it kinda stopped :smile:

cancan101 commented 1 year ago

This should be ready for review. This PR should have no breaking changes. There is an option to tighten the types on register but that would be a breaking change (requiring users to opt in to this new typing feature)