From 7ea02c8ab1e7846430beed508a8fe144cf0978ec Mon Sep 17 00:00:00 2001 From: Chris Kerr Date: Thu, 22 Dec 2022 15:35:19 +1000 Subject: [PATCH 1/7] update onmount typing to prevent async function return --- src/runtime/internal/lifecycle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index e75bbdc501f4..9717509190d8 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -31,7 +31,7 @@ export function beforeUpdate(fn: () => any) { * * https://svelte.dev/docs#run-time-svelte-onmount */ -export function onMount(fn: () => any) { +export function onMount(fn: (() => () => void) | (() => void | Promise)) { get_current_component().$$.on_mount.push(fn); } From eb97b539c9720c34a82870f3a78a775822fdf5c9 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Thu, 23 Feb 2023 17:45:51 +0900 Subject: [PATCH 2/7] enhance type --- src/runtime/internal/lifecycle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 9717509190d8..258f8b651d6a 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -31,7 +31,7 @@ export function beforeUpdate(fn: () => any) { * * https://svelte.dev/docs#run-time-svelte-onmount */ -export function onMount(fn: (() => () => void) | (() => void | Promise)) { +export function onMount(fn: (() => T extends Promise ? T : T extends Promise ? never : T)): void { get_current_component().$$.on_mount.push(fn); } From 1dec6e45b389e7bfcd5074b0b463baa0e4417ae1 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Thu, 23 Feb 2023 18:24:04 +0900 Subject: [PATCH 3/7] simplify --- src/runtime/internal/lifecycle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 258f8b651d6a..99f605daa43b 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -31,7 +31,7 @@ export function beforeUpdate(fn: () => any) { * * https://svelte.dev/docs#run-time-svelte-onmount */ -export function onMount(fn: (() => T extends Promise ? T : T extends Promise ? never : T)): void { +export function onMount(fn: () => T extends Promise<() => any> ? never : T): void { get_current_component().$$.on_mount.push(fn); } From f7c2a66d87b54f8b0567b3dc6a1bb16949fcafa9 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:14:19 +0200 Subject: [PATCH 4/7] force conflict so I can merge version-4 into this --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f240db6dce2c..b4debc8eeb6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # Svelte changelog - +d ## Unreleased * Add a11y warnings: From cda63cfd2e549f7f1f2d3b2c9017d4fbfefde28c Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:23:17 +0200 Subject: [PATCH 5/7] docs, test --- src/runtime/internal/lifecycle.ts | 2 + test/types/actions.ts | 108 +++++++++++++------------- test/types/create-event-dispatcher.ts | 8 +- test/types/on-mount.ts | 58 ++++++++++++++ 4 files changed, 118 insertions(+), 58 deletions(-) create mode 100644 test/types/on-mount.ts diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index f8583af8a3e8..9d68db96deea 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -27,6 +27,8 @@ export function beforeUpdate(fn: () => any) { * It must be called during the component's initialisation (but doesn't need to live *inside* the component; * it can be called from an external module). * + * If a function is returned _synchronously_ from `onMount`, it will be called when the component is unmounted. + * * `onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api). * * https://svelte.dev/docs#run-time-svelte-onmount diff --git a/test/types/actions.ts b/test/types/actions.ts index 2a604151a85b..7a0ca9771408 100644 --- a/test/types/actions.ts +++ b/test/types/actions.ts @@ -3,15 +3,15 @@ import type { Action, ActionReturn } from '$runtime/action'; // ---------------- Action const href: Action = (node) => { - node.href = ''; - // @ts-expect-error - node.href = 1; + node.href = ''; + // @ts-expect-error + node.href = 1; }; href; const required: Action = (node, param) => { - node; - param; + node; + param; }; required(null as any, true); // @ts-expect-error (only in strict mode) boolean missing @@ -20,34 +20,34 @@ required(null as any); required(null as any, 'string'); const required1: Action = (node, param) => { - node; - param; - return { - update: (p) => p === true, - destroy: () => {} - }; + node; + param; + return { + update: (p) => p === true, + destroy: () => {} + }; }; required1; const required2: Action = (node) => { - node; + node; }; required2; const required3: Action = (node, param) => { - node; - param; - return { - // @ts-expect-error comparison always resolves to false - update: (p) => p === 'd', - destroy: () => {} - }; + node; + param; + return { + // @ts-expect-error comparison always resolves to false + update: (p) => p === 'd', + destroy: () => {} + }; }; required3; const optional: Action = (node, param?) => { - node; - param; + node; + param; }; optional(null as any, true); optional(null as any); @@ -55,39 +55,39 @@ optional(null as any); optional(null as any, 'string'); const optional1: Action = (node, param?) => { - node; - param; - return { - update: (p) => p === true, - destroy: () => {} - }; + node; + param; + return { + update: (p) => p === true, + destroy: () => {} + }; }; optional1; const optional2: Action = (node) => { - node; + node; }; optional2; const optional3: Action = (node, param) => { - node; - param; + node; + param; }; optional3; const optional4: Action = (node, param?) => { - node; - param; - return { - // @ts-expect-error comparison always resolves to false - update: (p) => p === 'd', - destroy: () => {} - }; + node; + param; + return { + // @ts-expect-error comparison always resolves to false + update: (p) => p === 'd', + destroy: () => {} + }; }; optional4; const no: Action = (node) => { - node; + node; }; // @ts-expect-error second param no(null as any, true); @@ -96,10 +96,10 @@ no(null as any); no(null as any, 'string'); const no1: Action = (node) => { - node; - return { - destroy: () => {} - }; + node; + return { + destroy: () => {} + }; }; no1; @@ -113,32 +113,32 @@ no3; // @ts-expect-error update method given const no4: Action = (node) => { - return { - update: () => {}, - destroy: () => {} - }; + return { + update: () => {}, + destroy: () => {} + }; }; no4; // ---------------- ActionReturn const requiredReturn: ActionReturn = { - update: (p) => p.toString() + update: (p) => p.toString() }; requiredReturn; const optionalReturn: ActionReturn = { - update: (p) => { - p === true; - // @ts-expect-error could be undefined - p.toString(); - } + update: (p) => { + p === true; + // @ts-expect-error could be undefined + p.toString(); + } }; optionalReturn; const invalidProperty: ActionReturn = { - // @ts-expect-error invalid property - invalid: () => {} + // @ts-expect-error invalid property + invalid: () => {} }; invalidProperty; diff --git a/test/types/create-event-dispatcher.ts b/test/types/create-event-dispatcher.ts index d9fc6c65bdce..37e31fd1791c 100644 --- a/test/types/create-event-dispatcher.ts +++ b/test/types/create-event-dispatcher.ts @@ -1,10 +1,10 @@ import { createEventDispatcher } from '$runtime/internal/lifecycle'; const dispatch = createEventDispatcher<{ - loaded: never - change: string - valid: boolean - optional: number | null + loaded: never + change: string + valid: boolean + optional: number | null }>(); // @ts-expect-error: dispatch invalid event diff --git a/test/types/on-mount.ts b/test/types/on-mount.ts new file mode 100644 index 000000000000..cc60e9a50d56 --- /dev/null +++ b/test/types/on-mount.ts @@ -0,0 +1,58 @@ +import { onMount } from '$runtime/index'; + +// sync and no return +onMount(() => { + console.log("mounted"); +}); + +// sync and return value +onMount(() => { + return 'done'; +}); + +// sync and return sync +onMount(() => { + return () => { + return "done"; + }; +}); + +// sync and return async +onMount(() => { + return async () => { + const res = await fetch(''); + return res; + }; +}); + +// async and no return +onMount(async () => { + await fetch(''); +}); + +// async and return value +onMount(async () => { + const res = await fetch(''); + return res; +}); + +// @ts-expect-error async and return sync +onMount(async () => { + return () => { + return "done"; + }; +}); + +// @ts-expect-error async and return async +onMount(async () => { + return async () => { + const res = await fetch(''); + return res; + }; +}); + +// @ts-expect-error async and return any +onMount(async () => { + const a: any = null as any; + return a; +}); From 5c150827e1ce9ce317634023b1c3ce39d91266d1 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:28:30 +0200 Subject: [PATCH 6/7] lint --- test/types/on-mount.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/types/on-mount.ts b/test/types/on-mount.ts index cc60e9a50d56..47d272b8f57a 100644 --- a/test/types/on-mount.ts +++ b/test/types/on-mount.ts @@ -2,7 +2,7 @@ import { onMount } from '$runtime/index'; // sync and no return onMount(() => { - console.log("mounted"); + console.log('mounted'); }); // sync and return value @@ -13,7 +13,7 @@ onMount(() => { // sync and return sync onMount(() => { return () => { - return "done"; + return 'done'; }; }); @@ -39,7 +39,7 @@ onMount(async () => { // @ts-expect-error async and return sync onMount(async () => { return () => { - return "done"; + return 'done'; }; }); From 1246260fd512ab899758ec836f07a7fb99acfe9d Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Tue, 18 Apr 2023 10:31:33 +0200 Subject: [PATCH 7/7] Update src/runtime/internal/lifecycle.ts --- src/runtime/internal/lifecycle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 9d68db96deea..1c1726c29c5f 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -33,7 +33,7 @@ export function beforeUpdate(fn: () => any) { * * https://svelte.dev/docs#run-time-svelte-onmount */ -export function onMount(fn: () => T extends Promise<() => any> ? never : T): void { +export function onMount(fn: () => T extends Promise<() => any> ? "Returning a function asynchronously from onMount won't call that function on destroy" : T): void { get_current_component().$$.on_mount.push(fn); }