Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update onMount type definition to prevent async function return #8136

2 changes: 1 addition & 1 deletion src/runtime/internal/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void>)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function onMount(fn: (() => () => void) | (() => void | Promise<void>)) {
export function onMount(fn: (() => () => any) | (() => any | Promise<any>)) {

In this case, this will be a type error, right?
But fundamentally, there is no problem.

// api.js
export const fetch = () => Promise.resolve({foo: 'bar'});

// Component.svelte
<script>
  import { onMount } from 'svelte';
  import { fetch } from './api';
  onMount(() => fetch())
</script>

So IMO, it's better to use any type instead of void.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion but I think that this won't work to prevent a function return from an async onMount.

I am attempting to cause a typescript failure on arguments of type () => Promise<() => any>, but the introduction of () => any means that this remains a valid argument.

Given I only actually want to disallow this single type, perhaps the following is more appropriate:

type AnyExcept<Type, Disallowed> = Type & (Type extends Disallowed ? never : Type);
export declare function onMount<T>(fn: () => AnyExcept<T, Promise<() => any>>) {

Testing locally, this allows your example above and any other return from onMount except for the following:

onMount(async() => { // fails 
   return () => {
      /// anything
   }
})

get_current_component().$$.on_mount.push(fn);
}

Expand Down