Exploring the process of extending Shoelace web components with Typescript using Lit

Once I extended the <sl-button> component in Lit, I realized that TypeScript was not catching errors for incorrect attributes being passed. For instance, in the code snippet provided below, when I use <sl-button> with an incorrect attribute, TypeScript correctly displays an error. However, if I use <my-button> with a wrong attribute, TypeScript does not show any errors.

import SlButton from '@shoelace-style/shoelace/dist/components/button/button.js';
import {html} from 'lit';
import {customElement} from 'lit/decorators.js';

@customElement('my-button')
export default class MyButton extends SlButton {
  constructor() {
    super();
  }
}

export const Demo = () =>
  html`
    <my-button size="not-exists">Click here!</my-button> // shows no error on "size"
    <sl-button size="not-exists">Click here!</sl-button> // shows error on "size"
  `;

declare global {
  interface HTMLElementTagNameMap {
    'my-button': MyButton;
  }
}

Answer №1

It seems like everything is functioning correctly as intended. From what I gather, the issue you're encountering doesn't seem to be a TypeScript error, as TypeScript does not concern itself with HTML attributes; rather, it pertains to code completion in your editor.

My suspicion is that you are working with VS Code with customized data provided by Shoelace. This data informs VS Code about Shoelace elements that are registered. By accessing

dist/vscode.html-custom-data.json
, you can view each tag along with a compilation of available attributes.

If you are extending and renaming Shoelace elements, you will need to supply your own personalized data to VS Code.


Here are a couple points to consider:

Firstly, when you import components/button/button.js, you are essentially registering a Shoelace button. To clarify, your code registers both <sl-button> and <my-button> due to registration occurring upon import.

Secondly, it's worth noting that renaming Shoelace components is not recommended. Many functionalities rely on specific tag names, for instance, <sl-menu> anticipates child elements to be <sl-menu-item>. Similarly, <sl-tab-group> expects children of <sl-tab> and <sl-tab-panel>. Altering these names may result in unexpected complications.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: Prisma seed - encountering issues with undefined properties (unable to read 'findFirst')

I've encountered a strange issue when using prisma seed in my nextjs full-stack project that I can't seem to figure out. Normally, when running the app with `next dev`, everything works smoothly and the queries are executed without any problems. ...

The 'component' property is not found in the 'IntrinsicAttributes' type in this context

I am facing an issue with a component that is not compiling properly: export default function MobileNav({routes, currentRouteIndex, handlePressedRoutedIndex}: MobileNavProp) { ... return ( <React.Fragment> ... ...

The parent component remains visible in the Angular router

Within my appComponent, I have a layout consisting of a toolbar, footer, and main content. The main content utilizes the router-outlet directive structured as follows: <div class="h-100"> <app-toolbar></app-toolbar> < ...

Although VSCode is functioning properly, there seems to be a discrepancy between the VSCode and the TS compiler, resulting in an

While developing my project in VSCode, I encountered an issue with accessing req.user.name from the Request object for my Node.js Express application. VSCode was indicating that 'name' does not exist in the 'user' object. To address thi ...

Using SystemJS to re-export modules does not function properly

Attempting to re-export modules according to the TypeScript language website - using SystemJS as the module loader: app.ts import * as s from "./AllValidators"; // Some samples to try let strings = ["Hello", "98052", "101"]; // Validators to use let v ...

Is TypeScript failing to enforce generic constraints?

There is an interface defined as: export default interface Cacheable { } and then another one that extends it: import Cacheable from "./cacheable.js"; export default interface Coin extends Cacheable{ id: string; // bitcoin symbol: stri ...

Lack of code completion in Nuxt options API when using typescript

After setting up Nuxtjs with typescript, I noticed that there are no code completions in the template and script as expected based on the title. Here is the code: <script lang="ts"> import Vue from 'vue'; import { FeaturedJobs } ...

Error Encountered: Unhandled Runtime Error in Next.js with Firebase - TypeError: Unable to access the property 'initializeApp' as it is undefined

It's baffling why this error keeps appearing... my suspicion is directed towards this particular file. Specifically, firebaseAuth={getAuth(app)} might be the culprit. Preceding that, const app = initializeApp(firebaseConfig); is declared in "../f ...

How to extract and compare elements from an array using Typescript in Angular 6

I have created a new Angular component with the following code: import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { HttpClient } from '@angular/common/http'; @Compone ...

Is it possible to access NgbdModalContent properties from a different component?

If I have a component with a template containing an Edit button. When the user clicks on it, I want to load another component as a dynamic modal template. The component is named ProfilePictureModalComponent and it includes the Edit button: (Angular code h ...

Creating a RESTful API with Express, Firestore, Cloud Functions, and TypeScript

In my quest to create a REST API for my app, I've been delving into tutorials on Firestore & Cloud Functions. Unfortunately, all the ones I've come across are either outdated or simply don't work. This has been quite frustrating for me a ...

I am retrieving data from a service and passing it to a component using Angular and receiving '[object Object]'

Searching for assistance with the problem below regarding my model class. I've attempted various approaches using the .pipe.map() and importing {map} from rxjs/operators, but still encountering the error message [object Object] export class AppProfile ...

Having trouble retrieving values from radio buttons in Angular 2 forms

Having trouble displaying the values of radio button inputs in Angular 2 forms. ...

How to make an HTTP request in Angular 7 before the browser is closed

I'm attempting to trigger a POST HTTP request right before the browser closes. Essentially, I want to detect when the user closes the page and send a call, but the request isn't completing before shutdown. It seems like a traditional HTTP reque ...

Working with type-agnostic values in a type-agnostic list within a type-agnostic class using Typescript

I'm currently attempting to add a generic object to a list of other generic objects within a generic class. There seems to be an issue with the semantics, but I can't pinpoint exactly what the problem is. type EventCallback<I, O> = (event ...

Issue with useEffect() not receiving prop

Currently diving into the world of React and still in the learning process. I recently integrated a useEffect() hook in my code: import { fetchDetails } from "../../ApiServices/Details"; export interface RemoveModalProps { id: number; i ...

Refreshing the page causes the Angular/Ionic Singleton instance to be destroyed

I have a TypeScript singleton class that is responsible for storing the login credentials of a user. When I set these credentials on the login page and navigate to the next page using Angular Router.navigate (without passing any parameters), everything wor ...

How can I display a new module in Angular without navigating to it?

After following the tutorial at https://angular.io/guide/lazy-loading-ngmodules#create-a-feature-module-with-routing I set out to create the following: My goal is to have a dedicated module for all customer-related components accessible through the /cust ...

Display a dynamic array within an Angular2 view

I have a dynamic array that I need to display in the view of a component whenever items are added or removed from it. The array is displayed using the ngOnInit() method in my App Component (ts): import { Component, OnInit } from '@angular/core' ...

Tips for choosing a specific quantity and adjusting its value

Just starting out with Ionic 3 and looking for some help with the code. Can anyone assist me in understanding how to change the value of an item in a shopping cart and have the subtotal reflect that change? cart.ts private _values1 = [" 1 ", "2", " 3 "," ...