Svelte is an up-and-coming web framework which removes the need for any runtime libraries by adding a transpilation step in its build process. I first started using Svelte in January, seen in my optimisation blog post, and have since used it for my AI music generation tool MuseTree. In my experience, Svelte was blazing-fast and super simple to use, making me more productive than ever before. There was just one problem:
no TypeScript support 馃槺
Thankfully, support has slowly been improving over time. You can see this evolution in MuseTree, with more and more of its code slowly becoming TypeScript as wider support was implemented. It has finally reached the point where I feel comfortable saying that you can use Svelte with TypeScript, so it鈥檚 time to spread the word.
Get excited because we鈥檙e about to use my two favourite web technologies together. Find a spare 5 minutes and grab your nearest Svelte project (store-bought is fine) - it鈥檚 time to get stuck in.
All code samples in this post are taken from my example repo on GitHub
Update Your Build Config
These steps assume that you are starting with the official Svelte template
package.json
All that鈥檚 changed in package.json
is some new dev dependencies:
svelte-preprocess
lets us define preprocessing steps in rollup@rollup/plugin-typescript
registers TypeScript transpilation as one of those stepstypescript
is used by the TypeScript pluginsvelte-check
gives us compile-time type checking
You can install all of these at once with
npm i -D svelte-preprocess @rollup/plugin-typescript typescript svelte-check
then follow it up with npm install
to make sure all your dependencies are installed.
rollup.config.js
This is where the real changes happen.
First, update the input
from main.js
to main.ts
.
Then import our two new plugins at the top of the file:
import typescript from "@rollup/plugin-typescript";
import sveltePreprocess from "svelte-preprocess";
Next, we need to write our own plugin, as seen below.
This plugin runs svelte-check
, which is a command-line utility and not available as a rollup plugin directly.
Add this block to the bottom of your rollup config.
function typeCheck() {
return {
writeBundle() {
require('child_process').spawn('svelte-check', {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
}
Finally, at the top of the plugins list, add this block to register the three new plugins:
typeCheck(),
typescript({ sourceMap: !production }),
svelte({
preprocess: sveltePreprocess(),
dev: !production,
css: css => {
css.write("public/build/bundle.css");
}
}),
If you already have a svelte
section in your config, just replace it.
Now, every time we build our project, it will first type-check your code and transpile any TypeScript code into JavaScript.
tsconfig.json
Since we鈥檙e using TypeScript, we need a tsconfig.json
file to configure it.
Nothing special here, so if you鈥檙e experienced with TypeScript then use it like normal.
Otherwise, just create a file at the root of your project named tsconfig.json
containing this config:
{
"include": ["src/**/*"],
"exclude": ["node_modules/*", "public/*"],
"compilerOptions": {
"target": "ESNEXT",
"lib": ["ESNEXT", "dom"],
"module": "ESNEXT",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"strictNullChecks": true
}
}
main.js
Rename your entrypoint from main.js
to main.ts
.**
The first line, import App from './App.svelte';
will cause compilation errors as you can鈥檛 import a Svelte component into a TypeScript file.
Make the compiler ignore that error by adding // @ts-ignore
on the line above the import.
That鈥檚 everything! Your Svelte project is now configured to work with TypeScript.
Start Using TypeScript in Svelte
First things first, use an IDE that supports the Language Server Protocol. That includes VS Code, Atom, Sublime Text, and many others. It does not include JetBrains IDEs. Even as a die-hard JetBrains fan, I have resigned myself to using VS Code, which is the best supported. A full list of supported IDEs is available here.
Get the relevant Svelte extension - such as Svelte for VS Code. This adds in-IDE type checks for your Svelte code.
Then simply change your <script>
tag to <script lang="ts">
in each Svelte component, and you鈥檙e off!
Start using TypeScript, and you鈥檒l see any type errors in your IDE.
When you鈥檙e running the project, you鈥檒l also get type errors in the terminal:
Gotchas
The TypeScript support in Svelte isn鈥檛 perfect. There鈥檚 a few things you need to look out for:
- When importing a type into a Svelte component, you need to use the
import type
syntax. This means you might have two import statements for one file, like this:
import {searchBinaryTree} from "./tree"
import type {BinaryTree, BinaryTreeNode} from "./tree"
- To add types to a reactive declaration (
$:
), you have to do it in two steps. First, declare the variable using let with the correct type. Then add a reactive declaration like normal, without any types.
let inverseSliderValue: number;
$: inverseSliderValue = 10 - sliderValue;
-
The type definitions for the inline
style
on a DOM component are lying. They say they support JSX-like style objects, but really only support strings. If you want to use JSX, try thereact-style-object-to-css
library. -
Types are only checked inside the
<script>
tags, meaning you can have a text input withbind:value={stringVariable}
. -
The app won鈥檛 live-reload when you change a
.ts
file, only when you change the.svelte
files.
Conclusion
Svelte is amazing, and it鈥檚 even better with TypeScript. While support isn鈥檛 perfect, it鈥檚 good enough that I鈥檇 recommend it to anyone that鈥檚 used Svelte and TypeScript before. If you鈥檝e been waiting for TypeScript support before learning Svelte, now鈥檚 the time to get stuck in.
Make sure you check out the GitHub Repo which contains a working example project.