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

DO NOT MERGE: replace symbols with dumb classes #31

Closed
wants to merge 1 commit into from

Conversation

web-padawan
Copy link
Member

@web-padawan web-padawan commented Nov 26, 2019

Do not merge. This is a PR for discussion purposes only.
The wip/next branch has to be updated accordingly as we decide here.

Overview

The root problem is microsoft/TypeScript#17744 that is still unsolved.
See also "Related TS issues" below for more context.

These are 3 approaches that we might use for mixins that need to have protected methods, that can be overridden by the subclass including the super call.

1. Symbol approach

  • Not using protected methods in the mixins

  • Using Symbol as recommended by Elix instead

Pros

  • Methods are truly protected (can't be called from outside, e.g. by 3rd party code)

  • Methods are "public" in terms of TS and can be annotated on the interface

  • Explicit exports helping to make sure the consumers have compilation errors in case the new version was released an the internal API contracts of the protected methods have changed

  • Methods are excluded from the DevTools console's auto-complete list (good for user)

  • Symbols also avoid potential name conflicts if a component user wants to extend a custom element with their own methods.

Cons

  • Consumers have to import symbols if they need to override protected methods

  • Jump to definition is not ideal (jumps to the place where Symbol() is created)

2. Dumb class approach

  • Using protected methods in the mixins

  • Using abstract class SlottedItemsClass extends LitElement to "annotate" them

Pros

  • No need to import anything (except the mixin itself) for the consumer component

  • Methods are easy to access in the DevTools console (good for us as maintainers)

Cons

  • Both interface (for public API) and abstract class (for protected API) are needed

  • The abstract class ends up in the JS output (as empty class with no methods)

  • The mixin function needs to confusingly accept the argument with a type cast (instead of the actual expected class) in order to pick up the annotated protected methods from it:

// with dumb class: confusing
<T extends Constructor<SlottedItemsClass>>(base: T)

// without dumb class: clean
<T extends Constructor<LitElement>>(base: T)
  • Need for extra super check: super._focus && super._focus() - this is needed because the abstract classes mark methods using _focus?(), i.e. "possibly undefined"

  • Methods can be only called in tests with as any workaround

  • Jump to definition from the subclass goes to a dumb class

3. Public methods approach

  • Keep methods public, add them on the interface

  • Jump to definition works as expected

Pros

  • No extra code needed (symbols / dumb classes)

Cons

  • TS users would get protected methods listed in the code completion

  • Messing up public and protected API might require tweaks for tools

Summary

Personally, I like symbols approach more because it's cleaner, and it's not about "fighting with how TypeScrip works". But I'm ok with using the protected methods, too.

Related TS issues

@web-padawan web-padawan changed the title refactor: replace symbols with dumb classes DO NOT MERGE: replace symbols with dumb classes Nov 26, 2019
@web-padawan web-padawan force-pushed the wip/ts-class branch 2 times, most recently from aa08a74 to b539090 Compare November 27, 2019 13:26
@web-padawan
Copy link
Member Author

Agreed to use dumb classes for now. Closing in favor of vaadin/component-mixins#7

@web-padawan web-padawan closed this Dec 2, 2019
@web-padawan web-padawan deleted the wip/ts-class branch December 23, 2019 12:23
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

Successfully merging this pull request may close these issues.

None yet

1 participant