svelte
svelte copied to clipboard
Svelte 5 $props not working with lang='ts' without types
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
const { skill, visible } = $props(), u missing the call
I realized I am using $props
when I should be using $props()
Re-opening this because I think the compiler should provide a useful error in this situation