Skip to content

Possible loss of Attachments if restProps is processed using a "for in" loop. #15929

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

Open
HighFunctioningSociopathSH opened this issue May 15, 2025 · 2 comments

Comments

@HighFunctioningSociopathSH
Copy link

HighFunctioningSociopathSH commented May 15, 2025

Describe the bug

After checking why Attachments weren't working for my components, I found out that "for in" loops don't iterate over Symbols, and if they were used to process and return a new object of props from the restProps, there is a chance that Attachments would be lost in the process. As someone who doesn't have much experience with Symbols, it bugged me a little bit, and I was hoping there could be at least a warning in the docs for this issue.

Reproduction

Let's say someone wants to filter the restProps using a "for in" loop.

<script lang="ts">
  let { children, ...props } = $props();

  function processProps(props: Record<any, any>) {
    const processedProps: Record<any, any> = {};

    for (const key in props) {
      if (key !== "test") processedProps[key] = props[key];
    }

    return processedProps;
  }

  const processedProps = $derived(processProps(props));
</script>

<button {...processedProps}>
  {@render children?.()}
</button>

In the code above, the user accidentally removed the Attachments or any other property with a key of Symbol from their processedProps.
Of course, this could be fixed if you were to initially spread the original restProps inside the processedProps like so.

const processedProps: Record<any, any> = { ...props };

But when you update your Svelte version and then your Attachments don't work, it could be hard at first to know why this is happening, especially in a large code base, since it's silent with no error as well.

Logs

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (16) x64 12th Gen Intel(R) Core(TM) i7-12650H
    Memory: 6.61 GB / 15.63 GB
  Binaries:
    Node: 23.11.0 - C:\nvm4w\nodejs\node.EXE
    npm: 11.3.0 - C:\nvm4w\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (136.0.3240.64)
    Internet Explorer: 11.0.26100.1882

Severity

annoyance

@HighFunctioningSociopathSH
Copy link
Author

HighFunctioningSociopathSH commented May 15, 2025

I also checked that Object methods like Object.entries can also cause the accidental loss of Attachments.

So, for example something as simple as below will cause the loss of Attachments.

<script lang="ts">
  let { children, ...props } = $props();

  function processProps(props: Record<any, any>) {
    const entries = Object.entries(props);
    const processedProps = Object.fromEntries(entries);
    return processedProps;
  }

  const processedProps = $derived(processProps(props));
</script>

<button {...processedProps}>
  {@render children?.()}
</button>

@Thiagolino8
Copy link

Thiagolino8 commented May 16, 2025

Attachments have symbols as key
Properties that have symbols as key are not enumerable
For in and Object.keys only return enumerable properties
You can use Reflect.ownKeys to get all properties, including non-enumerable ones
Maybe the team could make attachments be declared as enumerable, but I can't think of a real case where that would be useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants