Skip to content

SvelteKit/TypeScript no longer accepts interfaces inside the script tag after module updates. #15912

Open
@timoanttila

Description

@timoanttila

Describe the bug

I had a working component library, but after updating the modules to the latest versions, Svelte/SvelteKit/TypeScript no longer lets me use interface Props. The GitHub repository still contains the previous version of the code. Here's an example of how I used TypeScript before: Breadcrumb, Button (same as the example here).

I tried changing all interface Props to type Props =, but that didn’t help. I also tried using a separate file for types ($lib/types.ts), but that didn’t work either.

Here are my module upgrades:

Package Old New
@sveltejs/kit ^2.20.8 ^2.21.0
eslint-plugin-svelte ^3.5.1 ^3.6.0
svelte ^5.28.2 ^5.28.6
typescript-eslint ^8.32.0 ^8.32.1

Error 1

[vite-plugin-svelte] [plugin vite-plugin-svelte] src/lib/Breadcrumbs.svelte (4:30): src/lib/Breadcrumbs.svelte:4:30 Unexpected token
[vite-plugin-svelte] [plugin vite-plugin-svelte] src/lib/Button.svelte (5:12): src/lib/Button.svelte:5:12 'interface' declarations must be followed by an identifier.

Error 2

This happened after I moved all types to their own file and imported them from there.

[vite-plugin-svelte] [plugin vite-plugin-svelte] src/lib/Button.svelte (40:5): src/lib/Button.svelte:40:5 Unexpected token

Example of my new import:

<script lang="ts">
  import {loading} from './index.ts'
  import type {ButtonView} from './types.ts'

  let {
    ariaControls,
    ariaExpanded,
    ariaLabel,
    ariaPopup,
    borderColor = 'content',
    borderSize = 0,
    children,
    color = 'white',
    colorBg = 'primary',
    control,
    disabled,
    extraClass,
    fill,
    fontWeight = 'bold',
    fullWidth,
    hover = 'secondary',
    hoverText = 'white',
    href,
    id,
    noCenter = false,
    noHeight,
    noPadding,
    noSpinner,
    onclick = undefined,
    preload,
    rel = 'noopener noreferrer',
    role,
    rounded = 'sm',
    spinnerColor = 'white',
    target,
    title,
    type,
    uppercase = true,
    value
  }: ButtonView = $props()

Here is my interface from types.ts

export interface ButtonView {
  children: Snippet
  ariaControls?: string | undefined
  ariaExpanded?: boolean | undefined
  ariaLabel?: string | undefined
  ariaPopup?: 'dialog' | 'listbox' | 'menu' | undefined
  borderColor?: 'content' | 'default' | 'primary'
  borderSize?: 0 | 1 | 2
  color?: string
  colorBg?: string
  control?: boolean
  disabled?: boolean
  extraClass?: string
  fill?: boolean
  fontWeight?: 'normal' | 'bold'
  fullWidth?: boolean
  hover?: 'black' | 'primary' | 'secondary' | 'success' | 'transparent'
  hoverText?: 'black' | 'primary' | 'secondary' | 'white'
  href?: string | undefined
  id?: string
  noCenter?: boolean
  noHeight?: boolean
  noPadding?: boolean
  noSpinner?: boolean
  onclick?: any
  preload?: 'hover' | 'tap'
  rel?: string
  role?: string
  rounded?: 'full' | 'lg' | 'none' | 'sm'
  spinnerColor?: 'black' | 'white'
  target?: '_blank' | '_top' | undefined
  title?: string | undefined
  type?: 'submit'
  uppercase?: boolean
  value?: string | number
}

tsconfig

{
  "extends": "./.svelte-kit/tsconfig.json",
  "compilerOptions": {
    "allowJs": true,
    "allowUnreachableCode": false,
    "checkJs": true,
    "esModuleInterop": true,
    "exactOptionalPropertyTypes": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "bundler",
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUncheckedIndexedAccess": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true
  }
}

Reproduction

Logs

System Info

System:
    OS: macOS 15.4.1
    CPU: (8) arm64 Apple M1
    Memory: 102.72 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.11.0 - /usr/local/bin/node
    Yarn: 1.22.22 - /usr/local/bin/yarn
    npm: 10.9.2 - /usr/local/bin/npm
    bun: 1.1.36 - ~/.bun/bin/bun
  Browsers:
    Safari: 18.4
  npmPackages:
    svelte: ^5.28.6 => 5.28.6

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting submitterneeds a reproduction, or clarification

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions