StephanB
StephanB

Reputation: 345

Array of typescript user-defined types/objects as property in Lit v2

I would like to convert my existing Javascript CustomElements/WebComponents (made with Lit v1 and ported to v2) to TypeScript.

Example:

export class MyElement extends LitElement {
  ...
  @property({type: String})
  name = 'World';
  ...
}

... or another one: https://github.com/lit/lit-element-starter-ts/blob/main/src/my-element.ts#L37

How can I define a property as an array of my custom typescript classes?

E.g. something like this:

export class MyElement extends LitElement {
  ...
  @property({type: Array<MyCustomClass>})
  customClassArray = [];
  // or: customClassArray = [new MyCustomClass("foo")]; 
  ...
}

Upvotes: 2

Views: 3019

Answers (2)

StephanB
StephanB

Reputation: 345

I think I have found a solution by myself, quite similiar to @arshia11d answer.

import { MyCustomClass } from './MyCustomClass';    

export class MyElement extends LitElement {
      @property({ type: Array }) //Array<MyCustomClass> throws ts(2303) error
      annotations: MyCustomClass[] = [];
    }

Type definition:

export interface IMyCustomClass {
  label: string;
}

export class MyCustomClass implements IMyCustomClass {
  label: string;

  constructor(
    _label: string
  ) {
    this.label = _label;
  }
}

Upvotes: 1

arshia11d
arshia11d

Reputation: 26

Lit's @property decorator is all about setting up a reactive property AND reflecting the attribute to the value (and vice versa if you turn on reflect: true). However, this conversion for HTML elements is tricky on non-string values, e.g. numbers shall be parsed to an actual number, for a boolean value the existence of the attribute means true etc.

That is why Lit needs type, to be able to choose the correct converter for the attribute value. Think of it as a type-hint or a converter-type regarding attribute/value conversion. Take a look at Lit's default converter.

Your actual types should be defined in TypeScript.

export class YourElement extends LitElement {
  @property({ type: Array })
  customClassArray = new Array<YourCustomClass>();
  // or: customClassArray = [new YourCustomClass()];
}

Upvotes: 1

Related Questions