Svelte: Components with Typed Props
Last updated:
How to set up typed props for svelte components.
Use Button.svelte.d.ts.
Given a Button svelte component:
// Button.svelte
<script lang="ts">
export let disabled: boolean = false;
export let kind: "primary"
| "danger"
| "secondary"
| "ghost"
| "outline" = "primary";
export let size: "sm" | "md" | "lg" = "md";
export let type: string = "button";
</script>
<button
class:btn={true}
class:btn-disabled={disabled}
class:btn-primary={kind === "primary"}
class:btn-secondary={kind === "secondary"}
class:btn-danger={kind === "danger"}
class:btn-ghost={kind === "ghost"}
class:btn-outline={kind === "outline"}
class:btn-sm={size === "sm"}
class:btn-md={size === "md"}
class:btn-lg={size === "lg"}
type={type}
tabindex="0"
disabled={disabled}
on:click
{...$$restProps}
>
<slot></slot>
</button>
In a file called Button.svelte.d.ts we can define our custom button props.
// Button.svelte.d.ts
import { SvelteComponentTyped } from "svelte";
export interface ButtonProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["button"]> {
disabled: boolean;
kind: "primary" | "danger" | "secondary" | "ghost" | "outline";
size: "sm" | "md" | "lg";
type: string = "button";
};
export default class Button extends SvelteComponentTyped<ButtonProps> {};
How to type custom events with your custom components
Add a custom event to your component using createEventDispatcher and
we will also need to decleare a new type for the data that will be passed once
the event is triggered.
In this example we’re adding a custom-click event and ButtonData type.
// Button.svelte
<script lang="ts">
// ....code
import { createEventDispatcher } from 'svelte';
import { ButtonData } from './Button.svelte.d.ts';
const dispatch = createEventDispatcher();
// data type
const btnData: ButtonData = {
name: 'hello'
};
</script>
<button
// ....code
{...$$restProps}
on:click
on:click={() => {
// make sure to dispatch the regular on:click event
dispatch("click");
// dispatch your custom click event
dispatch("custom-click", btnData);
}}
>
<slot></slot>
</button>
Define the new custom event type in Button.svelte.d.ts.
// Button.svelte.d.ts
import { SvelteComponentTyped } from "svelte";
export interface ButtonData {
name: string;
}
// ...ButtonProps code here...
export default class Button extends SvelteComponentTyped<
ButtonProps,
{
// click:custom-click: your custom event
// ButtonData: the type of the data sent
}
> {};
Usage
// Main.svelte
<script lang="ts">
import Button from "./Button.svelte";
</script>
<Button
on:click:custom-click={(e: CustomEvent<ButtonData>) => {
console.log(e.detail); // data from event dispatched
}}
> Click me!</Button>