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

refactor: hide internal API from TS definitions #2960

Merged
merged 5 commits into from
Nov 2, 2021

Conversation

web-padawan
Copy link
Member

Description

Same as #2881 but using a different approach inspired by #2881 (review)

Type of change

  • Refactor

assertType<DelegateFocusMixin>(checkbox);
assertType<SlotLabelMixin>(checkbox);
assertType<ActiveHost>(checkbox);
assertType<DisabledHost>(checkbox);
Copy link
Member Author

@web-padawan web-padawan Nov 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DisabledHost and KeyboardHost are no longer available through ActiveHost so we have to import them explicitly and add separate assertions. All the complex mixins (FieldMixin etc) work the same.

The main change in this PR is to use classes instead of interfaces to have protected methods, and the classes can't have multiple inheritance for obvious reasons. Unfortunately, it forces us to repeat ourselves.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UPD: DisabledMixinClass and KeyboardMixinClass are the new names, the rest of comment is still valid.

import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
import { CheckedMixinClass } from '@vaadin/field-base/src/checked-mixin.js';
import { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
import { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
Copy link
Member Author

@web-padawan web-padawan Nov 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the solution looks good, I will submit another PR to update remaining mixins e.g. ThemableMixin etc.

@@ -31,6 +31,7 @@
"polymer"
],
"dependencies": {
"@open-wc/dedupe-mixin": "^1.3.0",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now we only use Constructor type but we might want to also use dedupeMixin helper later.
It does pretty much the same thing as dedupingMixin from Polymer but in a different way.

Copy link
Member Author

@web-padawan web-padawan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a property is defined by two mixins, TypeScript intellisence shows both annotations.
Updated the DatePickerMixin to use "selected date" in value property to look like this:

tsdoc

@sonarcloud
Copy link

sonarcloud bot commented Nov 2, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@vursen
Copy link
Contributor

vursen commented Nov 2, 2021

There is one drawback I could see with the proposed solution. The TypeScript doesn't report any error in case a mixin overrides a parent method with a new one which call type doesn't match the parent call type.

Consider the following example:

// @filename focus-mixin.d.ts
export declare const FocusMixin: <T extends Constructor<HTMLElement>>(base: T) => T & Constructor<FocusMixinClass>;

export declare class FocusMixinClass {
  protected _setFocused(focused: boolean): void;
}
// @filename delegate-focus-mixin.d.ts
export declare function DelegateFocusMixin<T extends Constructor<HTMLElement>>(
  base: T
): T & Constructor<DelegateFocusMixinClass> & Constructor<FocusMixinClass>;

export declare class DelegateFocusMixinClass {
  protected _setFocused(focused: number/* doesn't match boolean, however, there is no error */): void;
}

Copy link
Member Author

@web-padawan web-padawan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vursen That's a good point but we can't provide a clean solution until microsoft/TypeScript#17744 is resolved.
The typeof class feature might make it possible when it lands microsoft/TypeScript#41587

The current approach is based on https://lit.dev/docs/composition/mixins/#typing-the-subclass

@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with platform 22.0.0.beta2 and is also targeting the upcoming stable 22.0.0 version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants