What is the process of bringing in a Svelte component into a Typescript file?

Can a Svelte component be imported into a Typescript file and successfully compiled by Rollup?

While the following code works fine as a Javascript file, it encounters errors when converted to Typescript, as the TS compiler struggles with a .svelte file:

import Component from './Component.svelte';

const foo = () => new Component({ target: document.body });

Is there a specific combination of rollup-plugin-svelte and @rollup/plugin-typescript that can preprocess the Svelte component in a way that the Typescript compiler can encompass the Svelte code?


For more context, boardgame.io features an in-browser debugging component constructed with Svelte, bundled in both a plain JS client and a React client component. We are in the process of updating our Rollup configuration to accommodate this particular scenario.

Answer №1

Just to elaborate on Rich's response, I was intrigued by the impact of importing Svelte in certain configurations.

the TS compiler struggles with a .svelte file

To address this issue (specifically in version 3.35.0), Svelte includes a file located at

svelte/types/runtime/ambient.d.ts
:

declare module '*.svelte' {
    export { SvelteComponentDev as default } from 'svelte/internal';
}

This enables the TS compiler to analyze .svelte files. Additionally, it defines the typings for all runtime functionalities accessible in a .svelte script, such as set_attributes() (refer to svelte/internal for more details). Merely using declare module '*.svelte' {} would cover only a portion, as you would also require those runtime declarations.

To ensure that the TypeScript compiler processes .svelte files, you must reference the types from that file,

svelte/types/runtime/ambient.d.ts
, in some way. This reference is indirectly made by the package's entrypoint typings file (specified in the types field of Svelte's package.json), types/runtime/index.d.ts, indicating that referencing the entrypoint typings file would be a recommended approach to stay resilient against future directory structure changes.

Incorporating @tsconfig/svelte/tsconfig.json effectively meets this requirement, as the referenced tsconfig file integrates the node module "svelte" through its compilerOptions.types property:

{
  // ... Omitted...

  "compilerOptions": {
    // ... Omitted...

    "types": ["svelte"]
  }
}

This inclusion signifies that the compilation environment will involve this reference:

/// <reference types="svelte" />

You could manually write the same line, though extending the Svelte tsconfig would align with possible future Svelte enhancements.

The import for side-effects approach serves the same purpose:

import "svelte";

Despite extending the Svelte tsconfig, I encountered the issue of Svelte types not being referenced. This was attributed to this line in my tsconfig:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  
  // ... Omitted...

  "compilerOptions": {
    // ... Omitted...

    "types": ["node"] // This overrides ["svelte"]!
  }
}

To rectify this issue, I replaced

"types": ["node"]
with
"types": ["node", "svelte"]
.

Answer №2

To optimize your project, consider integrating the @tsconfig/svelte plugin and making adjustments to your tsconfig.json configuration file:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": ["src/**/*"],
  "exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}

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

The element 'fontFamily' is not recognized within the 'ThemeOptions' type in MUI theming

I'm diving into the world of React and MUI by building my own dashboard from scratch. Let's take a look at my App.tsx file: import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; i ...

Navigate through each file or image within a directory using Angular

I am facing a challenge with my app where each product has a gallery containing a random number of images, each with a completely unique name. These images are located in /src/assets/images/products/:id/. Currently, I am struggling to loop through and add ...

What could be causing NgModel to fail with mat-checkbox and radio buttons in Angular?

I am working with an array of booleans representing week days to determine which day is selected: selectedWeekDays: boolean[] = [true,true,true,true,true,true]; In my HTML file: <section> <h4>Choose your days:</h4> <mat-che ...

What is the correct way to destructure a tuple in Typescript when only certain values will be assigned to new variables?

When writing code, I frequently encounter situations that resemble the following: function example(parameter: string) { const tuple = [ "newParameterValue", "newVariableValue" ] let newVar; [parameter, newVar] = tuple; } ( ...

Error code 2769 in Typescript occurs when attempting to transfer process information to the data state in order to utilize it within a modal

I'm encountering an issue while trying to pass a process to a setData state from a .map function in order to display it on a modal. The error message I'm receiving is: "No overload matches this call. Overload 1 of 2, '(props: { compone ...

Extract data from an HTTP request and assign it to variables using filter and map in Angular

I need to extract data from an http get request and assign it to 3 separate variables once fetched. Data: [ { reportId: 1, results1: [{ name: "TotalReferralsMade", optionId: 3082, factor: 1, description: null ...

Provide a boolean value of true or false to indicate whether all delete operations were successfully completed

Currently, I am using Sequelize, GraphQL, and Typescript for my coding. Within my database, I have two tables named RecordInformation and OtherDescription. The RecordInformation table contains a foreign key called "OtherID" which references the OtherDescri ...

connect a column from a separate array in pdfmake

In my current project, I am looking to link the values of an array that is different from the one present in the initial two columns. Is this achievable? (The number of partialPrice values aligns with the number of code entries). Despite several attempts ...

Change a nullable string property within an interface to a non-nullable string property

Looking at two interfaces, one with a nullable vin and the other without: interface IVehicle { vin: string | null; model: string; } interface IVehicleNonNullVin { vin: string; model: string; } The goal is to convert a model from IVehicle ...

Challenging Issue: "The 'any' type cannot be assigned to the 'never' type"

Currently facing a challenging Typescript problem that has me puzzled. The issue arises at the line themeToChange[tileId][key] = value; The error message states Type 'any' is not assignable to type 'never' This error is directly rela ...

Learning to retrieve the value from a dynamically generated input tag in a TypeScript file

<div *ngFor="let task of arrayList"> <input id="task.fieldName" *ngIf="task.key === 'Others'" type="text" class="form-control"> </div> When dealing with dynamically created input fields based on a condition, the challenge is ac ...

Discovering subtype relationships in JSON with TypeScript

Consider the scenario where there are parent and child typescript objects: class Parent { private parentField: string; } class Child extends Parent { private childField: string; } Suppose you receive a list of JSON objects for both types via a R ...

Best practices for safely handling dynamic keys in Typescript

I am searching for a secure method to create keyed objects in this manner: interface Types { RED: 'RED'; BLUE: 'BLUE'; GREEN: 'GREEN'; } type TypeKeys = keyof Types; const COLORS: Types = { RED: 'RED', B ...

Type guard does not narrow down the union type

Explore the following code snippet: type UnionType = 'foo' | 'bar' | 'baz' const obj = { foo: 'huh', bar: 'hmm' } function func(input: UnionType) { if(input in obj) { input } } In ...

Exploring Observable Functionality in Angular 6

I've been grappling with understanding Angular Observables, but I've managed to get it working. My goal is to fetch data for my dynamic navigation bar. I successfully verified whether the user is logged in or not and displayed the Login or Logout ...

Angular 8 HTTP Interceptor causing issues with subscriptions

I'm currently in the process of setting up an Angular 8 project that will allow me to mock API calls using HTTP INTERCEPTORS. My approach involves adding a --configuration=mock flag to my ng serve script so that the interceptor is injected into my app ...

When the *ngFor directive disrupts the CSS Grid Layout, resulting in all items being displayed in a single column

I am a beginner in the world of programming and web development. Currently, I am working on building my own personal website. My goal is to arrange boxes in a grid with 4 columns, similar to the layout you can find at this link: Each box represents an ob ...

Is it possible in Typescript to pass method signature with parameters as an argument to another method?

I am working on a React app where I have separated the actions into a different file from the service methods hoplite.actions.ts export const fetchBattleResult = createAsyncThunk<Result>( 'battle/fetchBattleResult', HopliteService.battleRe ...

The error message states that the property 'registerUser' is not found on the class 'UserController'

In the controller file, I exported two functions (registerUser and loginUser) as default. No errors were thrown at that stage, but when attempting to access the routes, an error occurred stating - Property 'registerUser' does not exist on type &a ...

Error in Typescript TS2322: Observable Type 'boolean | {}' - Using Angular 5 and Typescript 2.4.2

After upgrading from version 4 to 5, I'm puzzled by the plethora of TypeScript TS2322 errors I'm encountering. The migration involved setting up a new Angular project with the Angular CLI. Angular CLI: 1.5.5 Node: 8.9.1 OS: darwin x64 Angular: 5 ...