From 12375197ae2ee6650f3a5a84258758a314cbb490 Mon Sep 17 00:00:00 2001 From: Michael Cousins Date: Tue, 11 Feb 2025 12:54:38 -0500 Subject: [PATCH] fix(types): fix types when using legacy components in Svelte 5 --- src/__tests__/fixtures/Typed.svelte | 5 +++++ src/__tests__/render-runes.test-d.ts | 32 +++++++++++++++++++++++++++- src/component-types.d.ts | 14 ++++++------ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/__tests__/fixtures/Typed.svelte b/src/__tests__/fixtures/Typed.svelte index 44960ab..383214f 100644 --- a/src/__tests__/fixtures/Typed.svelte +++ b/src/__tests__/fixtures/Typed.svelte @@ -1,9 +1,14 @@

hello {name}

count: {count}

+ diff --git a/src/__tests__/render-runes.test-d.ts b/src/__tests__/render-runes.test-d.ts index 2d0c69f..48d9d27 100644 --- a/src/__tests__/render-runes.test-d.ts +++ b/src/__tests__/render-runes.test-d.ts @@ -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() + }) +}) diff --git a/src/component-types.d.ts b/src/component-types.d.ts index 9f707c2..8300243 100644 --- a/src/component-types.d.ts +++ b/src/component-types.d.ts @@ -45,17 +45,17 @@ export type Props = ComponentProps * 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 extends LegacyComponent - ? C - : C extends ModernComponent +export type Exports = IS_MODERN_SVELTE extends true + ? C extends ModernComponent ? 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 LegacyComponent - ? LegacyConstructorOptions> - : Parameters, Exports>>[1] +export type MountOptions = IS_MODERN_SVELTE extends true + ? Parameters, Exports>>[1] + : LegacyConstructorOptions>