Skip to content

Svelte 5 $props not working with lang='ts' without types #10374

@timscodebase

Description

@timscodebase

Describe the bug

Many of the components for my personal website require the use of prop. This is obviously a basic usage of Svelte and so is TypeScript so I thought it odd when I upgraded to Svelte 5 and none of my components worked when I converted my props to the new runes syntax. I was on a last ditch effort after a long walk that I decided to fix the type errors.

Reproduction

This component is a great example:
https://github.com/timscodebase/design-tim/blob/main/src/lib/components/SkillGrid/Skill.svelte

<script lang="ts">
	import { onMount } from 'svelte'
	import { scale } from 'svelte/transition'
	import { Chip, Link } from '$lib'
	import { viewport, slugify } from '$utils'
	import { navColor } from '$stores'
	import type { SkillType } from '$lib/types'

	const { skill, visible } = $props<{ skill: SkillType; visible: boolean }>()
	let isVisible = $state(visible)

	onMount(() => {
		const box = document.querySelector('.outer')
		if (!isVisible && viewport.isIn(box)) {
			isVisible = true
		}

		document.addEventListener(
			'scroll',
			function () {
				if (!isVisible && viewport.isIn(box)) {
					isVisible = true
				}
			},
			{
				passive: true
			}
		)
	})

	function onMouseover() {
		navColor.set(skill.category)
	}
</script>

<div class="outer">
	{#if isVisible}
		<div
			tabindex="0"
			on:touchstart={onMouseover}
			on:mouseover={onMouseover}
			on:focus={onMouseover}
			class={`skill ${skill.category}`}
			in:scale={{ duration: 500 }}
			out:scale={{ duration: 500 }}
		>
			<h3>{skill.name}</h3>

			<p class="info">
				<b class="bold"
					>{skill.yearsExp}
					{parseInt(skill.yearsExp) > 1 ? ` years` : `year`}</b
				>
				<br />{skill.category}
				<br /><b class="bold">{skill.level}</b>
			</p>

			<h4>Used At</h4>
			<ul class="usedAt">
				<!-- alphabetize list -->

				{#each skill.usedAt.sort() as usedAt}
					<Chip liClass={skill.category}>
						<Link href={`/jobs/#${slugify(usedAt)}`}>{usedAt}</Link>
					</Chip>
				{/each}
			</ul>
		</div>
	{/if}
</div>

The above code works.

If you change the prop to:

const { skill, visible } = $props

I get the error below indicating that the props are undefined.

Logs

chunk-O7IYX3P4.js?v=b0604889:690 Uncaught TypeError: Cannot read properties of undefined (reading 'yearsExp')
    at Skill.svelte:43:14
    at chunk-2TIX4LCG.js?v=b0604889:1197:33
    at execute_signal_fn (chunk-O7IYX3P4.js?v=b0604889:570:7)
    at execute_effect (chunk-O7IYX3P4.js?v=b0604889:705:31)
    at schedule_effect (chunk-O7IYX3P4.js?v=b0604889:777:5)
    at internal_create_effect (chunk-O7IYX3P4.js?v=b0604889:1284:5)
    at render_effect (chunk-O7IYX3P4.js?v=b0604889:1360:10)
    at Module.text_effect (chunk-2TIX4LCG.js?v=b0604889:1197:3)
    at Skill.svelte:38:30
    at chunk-2TIX4LCG.js?v=b0604889:1928:9

System Info

ystem:
    OS: macOS 14.4
    CPU: (8) arm64 Apple M1
    Memory: 92.23 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
    Yarn: 1.22.21 - /opt/homebrew/bin/yarn
    npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm
    pnpm: 8.14.3 - ~/Library/pnpm/pnpm
    bun: 1.0.25 - ~/.bun/bin/bun
  Browsers:
    Chrome Canary: 123.0.6274.0
    Safari: 17.4
    Safari Technology Preview: 17.4
  npmPackages:
    svelte: 5.0.0-next.37 => 5.0.0-next.37

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    compilerChanges relating to the compiler

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions