eclipsesource / tabris-js

Create native mobile apps in JavaScript or TypeScript.
https://tabrisjs.com
BSD 3-Clause "New" or "Revised" License
1.4k stars 172 forks source link

Cannot pass function argument to custom component #2263

Open cpetrov opened 1 year ago

cpetrov commented 1 year ago

Problem description

When attempting to pass a function argument to a custom component, the TS compiler raises an error. Example:

import { contentView, Composite, Properties } from 'tabris';
import { component, property } from 'tabris-decorators';

export class App {
  public start() {
    contentView.append(
      <CustomComponent myFunctionProp={() => 'foo'} myStringProp='foo'/>,
      /**
       * Type '{ myFunctionProp: () => string; myStringProp: string; }' is not assignable to type 'JSXCompositeAttributes<CustomComponent, Widget<any>>'.
       * Property 'myFunctionProp' does not exist on type 'JSXCompositeAttributes<CustomComponent, Widget<any>>'.ts(2322)
       */
      new CustomComponent({ myFunctionProp: () => 'foo', myStringProp: 'foo' })
     /**
      * Argument of type '{ myFunctionProp: () => string; myStringProp: string; }' is not assignable to parameter of type 'Properties<CustomComponent>'.
      * Object literal may only specify known properties, and 'myFunctionProp' does not exist in type 'Properties<CustomComponent>'.ts(2345)
      */
    );
  }
}

@component
class CustomComponent extends Composite {
  @property public myFunctionProp: () => any;
  @property public myStringProp: string;

  constructor(properties: Properties<CustomComponent>) {
    super();
    this.set(properties);
  }
}

As a workaround, the jsxAttributes type can be overwritten, see https://docs.tabris.com/latest/declarative-ui.html#adding-special-attributes.

Expected behavior

One should be able to use properties with function types in custom components.

Environment