#1708·mitosis

Lit Reactive Properties are Incorrectly Typed

Author: taylorfsteeleCreated Mar 3, 2025Updated Mar 3, 2025
Labelsbug

I am interested in helping provide a fix!

Yes

Which generators are impacted?

  • All
  • Angular
  • HTML
  • Preact
  • Qwik
  • React
  • React-Native
  • Solid
  • Stencil
  • Svelte
  • Vue
  • Web components

Reproduction case

https://mitosis.builder.io/playground/?code=MYewdgzgLgBAIgUQGIEECqAZAKgfQGooZoIDKMAvDAN4BQMMoIANgHICGAtgKYBcMARIyb8ANDQC%2BAbho0uADwAOIAE6wAJlwBmbAK5NYmnWGBQAluBgI5nBUy4BhEByVguYKAAoFykAogBKajoYZS4oHWUwGA9g%2BgAeNVMANwA%2BWPoYAAkuJiYQGHkbOwYnFzdYKm9fCAA6IXZuGAB%2BJvhkdGx8QmISOpBmBq5xdLiAekTU4P9pYaA%3D

Expected Behaviour

When given a props with types, the emitted lit component's reactive property's type decorator should be properly typed.

The Mitosis component:

bash
export type ExampleComponentProps = {
  coolName?: string;
};

const DEFAULT_VALUES = {
  coolName: "cool",
};

export default function ExampleComponent(props: ExampleComponentProps) {
  return (
    <div>
      Hello example component {props.coolName ?? DEFAULT_VALUES.coolName}
    </div>
  );
}

Should emit a Lit component of

bash
const DEFAULT_VALUES = {
  coolName: "cool",
};

import { LitElement, html, css } from "lit";
import { customElement, property, state, query } from "lit/decorators.js";

export type ExampleComponentProps = {
  coolName?: string;
};

@customElement("example-component")
export default class ExampleComponent extends LitElement {
  createRenderRoot() {
    return this;
  }

  @property()
  coolName?: string;

  render() {
    return html`<div>Hello example component ${this.coolName ?? DEFAULT_VALUES.coolName}</div>`;
  }
}

Actual Behaviour

The emitted lit component types the property as any:

bash
const DEFAULT_VALUES = {
  coolName: "cool",
};

import { LitElement, html, css } from "lit";
import { customElement, property, state, query } from "lit/decorators.js";

@customElement("example-component")
export default class ExampleComponent extends LitElement {
  createRenderRoot() {
    return this;
  }

  @property() coolName: any;

  render() {
    return html`

          <div>Hello example component ${
            this.coolName ?? DEFAULT_VALUES.coolName
          }</div>

        `;
  }
}

Additional Information

It currently looks like the compiler generates these properties from props, which just looks like strings of the props. Matching up the corresponding type from the types array also seems difficult, since it's a string of the emitted TypeScript type. Is it possible to change how props and types are collected to facilitate this? Or is that too complex of a solution?