Skip to content

Commit

Permalink
fix(types): fix types when using legacy components in Svelte 5 (#424)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcous authored Feb 11, 2025
1 parent 5aa405a commit e86dada
Showing 3 changed files with 43 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/__tests__/fixtures/Typed.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
export let name: string
export let count: number
export const hello: string = 'hello'
const dispatch = createEventDispatcher<{ greeting: string }>()
</script>

<h1>hello {name}</h1>
<p>count: {count}</p>
<button on:click={() => dispatch('greeting', 'hello')}>greet</button>
32 changes: 31 additions & 1 deletion src/__tests__/render-runes.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { expectTypeOf } from 'expect-type'
import { describe, test } from 'vitest'
import { describe, test, vi } from 'vitest'

import * as subject from '../index.js'
import LegacyComponent from './fixtures/Typed.svelte'
import Component from './fixtures/TypedRunes.svelte'

describe('types', () => {
@@ -37,3 +38,32 @@ describe('types', () => {
}>()
})
})

describe('legacy component types', () => {
test('render accepts events', () => {
const onGreeting = vi.fn()
subject.render(LegacyComponent, {
props: { name: 'Alice', count: 42 },
events: { greeting: onGreeting },
})
})

test('component $set and $on are not allowed', () => {
const onGreeting = vi.fn()
const { component } = subject.render(LegacyComponent, {
name: 'Alice',
count: 42,
})

expectTypeOf(component).toMatchTypeOf<{ hello: string }>()

// @ts-expect-error: Svelte 5 mount does not return `$set`
component.$on('greeting', onGreeting)

// @ts-expect-error: Svelte 5 mount does not return `$set`
component.$set({ name: 'Bob' })

// @ts-expect-error: Svelte 5 mount does not return `$destroy`
component.$destroy()
})
})
14 changes: 7 additions & 7 deletions src/component-types.d.ts
Original file line number Diff line number Diff line change
@@ -45,17 +45,17 @@ export type Props<C extends Component> = ComponentProps<C>
* In Svelte 5, this is the set of variables marked as `export`'d.
* In Svelte 4, this is simply the instance of the component class.
*/
export type Exports<C> = C extends LegacyComponent
? C
: C extends ModernComponent<any, infer E>
export type Exports<C> = IS_MODERN_SVELTE extends true
? C extends ModernComponent<any, infer E>
? E
: never
: C & { $set: never; $on: never; $destroy: never }
: C

/**
* Options that may be passed to `mount` when rendering the component.
*
* In Svelte 4, these are the options passed to the component constructor.
*/
export type MountOptions<C extends Component> = C extends LegacyComponent
? LegacyConstructorOptions<Props<C>>
: Parameters<typeof mount<Props<C>, Exports<C>>>[1]
export type MountOptions<C extends Component> = IS_MODERN_SVELTE extends true
? Parameters<typeof mount<Props<C>, Exports<C>>>[1]
: LegacyConstructorOptions<Props<C>>

0 comments on commit e86dada

Please sign in to comment.