vaadin/vaadin-core

Add TypeScript definition files

tomivirkki opened this issue ยท 11 comments

Add TypeScript definition files

Some basic issues I am seeing currently which I hope this would solve:

  1. Finding a dialog element from the shadow root and configuring it

Issue #1: Can't import DialogElement from @vaadin/vaadin-dialog but instead need to do

import "@vaadin/vaadin-dialog";
import { DialogElement } from "@vaadin/vaadin-dialog/src/vaadin-dialog";

Issue #2: Can't cast the return value of querySelector to DialogElement

    this.dialog = this.shadowRoot.querySelector<DialogElement>("#dialog");

Type 'DialogElement' does not satisfy the constraint 'Element'.

Issue #3: Can't cast the event target type to ComboBoxElement

<vaadin-combo-box @change="${(e: CustomEvent) => (field.type = (e.target as ComboBoxElement).value)}">

would be awesome if e was automatically of a type where target is ComboBoxElement. Not sure if this is doable and would also fail if the change event was from a child element of a different type. Otherwise the issue is probably the same as nr 2

Issue #1

This should also work

import "@vaadin/vaadin-dialog";
const DialogElement = customElements.get('vaadin-dialog');

Also see Polymer/polymer#4556 (comment)

There seems to be some problems with namespace/@memberof

For instance, vaadin-themable-mixin.html contains

/**
 * @polymerMixin
 * @memberof Vaadin
 */
Vaadin.ThemableMixin = superClass => class VaadinThemableMixin extends Vaadin.ThemePropertyMixin(superClass) {```
but the P3 version contains

/**

  • @polymerMixin
    */
    export const ThemableMixin = superClass => class VaadinThemableMixin extends ThemePropertyMixin(superClass) {

This leads to `vaadin-themable-mixin.d.ts` not containing any namespace but all imports from other components seem to assume the namespace

Having @memberof Vaadin in every component causes an unnecessary namespace Vaadin to be added to each and every TS file. Is this really necessary?

The TS generator reads JSDoc and not what the class really extends it seems, so having

 * @mixes ElementMixin
 * @mixes ListMixin
 * @mixes ThemableMixin
 */
class TabsElement extends
  ElementMixin(
    ListMixin(
      ThemableMixin(
        mixinBehaviors([IronResizableBehavior], PolymerElement)))) {

generates

class TabsElement extends
  ElementMixin(
  ListMixin(
  ThemableMixin(
  Object))) {

which means TabsElement is not an HTMLElement

so you need to add

 * @mixes IronResizableBehavior

to get

class TabsElement extends
  ElementMixin(
  ListMixin(
  ThemableMixin(
  IronResizableBehavior(
  Object)))) {

which is still wrong since PolymerElement is missing

This might also somehow be related to unclear errors output by gen-typescript-declarations:

import { PolymerElement } from '@polymer/polymer/polymer-element.js';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file:///.../vaadin-tabs/src/vaadin-tab.js(6,1) warning [cant-resolve-module-specifier] - Cannot resolve module specifier with resolution algorithm: none

for a lot of imports

Is there any potential that type declarations may be vended prior to typescript code migration?

I have done a research on what would it take to generate typings after polymer modulizer.

Example for vaadin-progress-bar: vaadin/vaadin-progress-bar@7e3a590

How to run it locally:

  1. Clone the repo
git clone https://github.com/vaadin/vaadin-progress-bar && cd vaadin-progress-bar
  1. Checkout the branch:
git checkout ts-test
  1. Install tools globally:
npm i polymer-modulizer magi-cli -g
  1. Install dependencies:
npm i && bower i
  1. Run P3 conversion:
magi p3-convert --out . --import-style=name
  1. Delete bower_components:
rm -rf bower_components
  1. Re-install dependencies:
npm i
  1. Generate typings:
npm run generate-typings

The generated TS definition files (with all the comments removed) are below:

src/vaadin-progress-bar.d.ts

import {PolymerElement} from '@polymer/polymer/polymer-element.js';

import {ProgressMixin} from './vaadin-progress-mixin.js';

import {ThemableMixin} from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

import {ElementMixin} from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js';

import {html} from '@polymer/polymer/lib/utils/html-tag.js';

declare class ProgressBarElement extends
  ProgressMixin(
  ThemableMixin(
  ElementMixin(
  PolymerElement))) {
}

declare global {
  interface HTMLElementTagNameMap {
    "vaadin-progress-bar": ProgressBarElement;
  }
}

export {ProgressBarElement};

src/vaadin-progress-mixin.d.ts

export {ProgressMixin};

declare function ProgressMixin<T extends new (...args: any[]) => {}>(base: T): T & ProgressMixinConstructor;

interface ProgressMixinConstructor {
  new(...args: any[]): ProgressMixin;
}

export {ProgressMixinConstructor};

interface ProgressMixin {
  value: number|null|undefined;

  min: number|null|undefined;

  max: number|null|undefined;

  indeterminate: boolean|null|undefined;
  ready(): void;
  _normalizedValueChanged(value: any, min: any, max: any): void;
  _valueChanged(newV: any, oldV: any): void;
  _minChanged(newV: any, oldV: any): void;
  _maxChanged(newV: any, oldV: any): void;

  _normalizeValue(value: any, min: any, max: any): any;
}

vaadin-progress-bar.d.ts

export * from './src/vaadin-progress-bar.js';

Tested also with vaadin-combo-box to verify if types for dataProvider can be created.

See the commit: vaadin/vaadin-combo-box@5b35538

src/vaadin-combo-box-data-provider-mixin.js

export {ComboBoxDataProviderMixin};

declare function ComboBoxDataProviderMixin<T extends new (...args: any[]) => {}>(base: T): T & ComboBoxDataProviderMixinConstructor;

interface ComboBoxDataProviderMixinConstructor {
  new(...args: any[]): ComboBoxDataProviderMixin;
}

export {ComboBoxDataProviderMixinConstructor};

interface ComboBoxDataProviderMixin {
  pageSize: number|null|undefined;

  size: number|null|undefined;

  dataProvider: ComboBoxDataProvider|null;
  _pendingRequests: any;
  _dataProviderClearFilter(dataProvider: ComboBoxDataProvider|null, opened: boolean, value: string): void;
  ready(): void;
  _dataProviderFilterChanged(): void;
  _ensureFirstPage(opened: any): void;
  _shouldLoadPage(page: any): any;
  _loadPage(page: any): void;
  _getPageForIndex(index: any): any;

  clearCache(): void;
  _sizeChanged(size?: any): void;
  _pageSizeChanged(pageSize: any, oldPageSize: any): void;
  _dataProviderChanged(dataProvider: ComboBoxDataProvider|null, oldDataProvider: ComboBoxDataProvider|null): void;
  _ensureItemsOrDataProvider(restoreOldValueCallback: any): void;
  _warnDataProviderValue(dataProvider: ComboBoxDataProvider|null, value: string|null): void;
}

import {ComboBoxDataProvider} from './vaadin-combo-box-data-provider.d.ts';

Note: magi-cli has been updated, please use the latest version 0.25.2.

The steps 7 and 8 described at #186 (comment) are now done by magi p3-convert.

The versions that have TypeScript definitions are listed below:

Core components

 Component  Version
 vaadin-accordion  v1.2.0-alpha1
 vaadin-app-layout  v2.2.0-alpha1
 vaadin-button  v2.4.0-alpha1
 vaadin-checkbox  v2.4.0-alpha1
 vaadin-combo-box  v5.3.0-alpha1
 vaadin-context-menu  v4.5.0-alpha1
 vaadin-custom-field  v1.2.0-alpha1
 vaadin-date-picker  v4.3.0-alpha1
 vaadin-date-time-picker  v1.3.0-alpha1
 vaadin-details  v1.2.0-alpha1
 vaadin-dialog  v2.5.0-alpha1
 vaadin-form-layout  v2.3.0-alpha1
 vaadin-grid  v5.7.0-alpha2
 vaadin-item  v2.3.0-alpha1
 vaadin-list-box  v1.4.0-alpha1
 vaadin-login  v1.2.0-alpha2
 vaadin-menu-bar  v1.2.0-alpha1
 vaadin-notification  v1.6.0-alpha1
 vaadin-ordered-layout  v1.4.0-alpha1
 vaadin-progress-bar  v1.3.0-alpha1
 vaadin-radio-button  v1.4.0-alpha1
 vaadin-select  v2.3.0-alpha1
 vaadin-split-layout  v4.3.0-alpha1
 vaadin-tabs  v3.2.0-alpha1
 vaadin-text-field  v2.7.0-alpha1
 vaadin-time-picker  v2.3.0-alpha2
 vaadin-upload  v4.4.0-alpha1

Pro components

 Component  Version
 vaadin-crud  v1.3.0-alpha1
 vaadin-board  v2.2.0-alpha1
 vaadin-charts  v7.0.0-alpha2
 vaadin-confirm-dialog  v1.3.0-alpha1
 vaadin-cookie-consent  v1.2.0-alpha1
 vaadin-grid-pro  v2.2.0-alpha1
 vaadin-rich-text-editor  v1.3.0-alpha1

mixins

 Component  Version
 vaadin-themable-mixin  v1.6.1
 vaadin-element-mixin  v2.4.1
 vaadin-control-state-mixin  v2.2.1
 vaadin-list-mixin  v2.5.0
 vaadin-overlay  v3.5.0

Closing as done.