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

Proposal: Switch props from "export let" to "import let" #3454

Closed
KieranP opened this issue Aug 23, 2019 · 7 comments
Closed

Proposal: Switch props from "export let" to "import let" #3454

KieranP opened this issue Aug 23, 2019 · 7 comments

Comments

@KieranP
Copy link

KieranP commented Aug 23, 2019

Describe the solution you'd like
Whilst going through the tutorial, I was confused by the same use of export let name for both receiving in props from parent, and passing value up to the parent through bind. It seems that receiving props in using "export let" doesn't really have the right connotation.

Describe alternatives you've considered
Consider changing the syntax for receiving props to be import let name. Then you would have a clear distinction between what comes in, and what goes out.

Contrived example.

form.svelte

<script>
  import Field from './field.svelte'
  let name;
</script>

<Field type='text' label='Name' bind:value={name} />

field.svelte

<script>
  import let type;
  import let label;
  export let value;
</script>

<p>
  <label>{label}</label>
  <input type={type} bind:value={value} />
</p>

How important is this feature to you?
It's not critical, but for the above example, it makes things very clear what comes in and out. If both variable declarations were export, which is currently required, it makes things a bit confusing and requires code comments to explain.

@antony
Copy link
Member

antony commented Aug 23, 2019

This is invalid Javascript, and would break existing tooling.

Being valid Javascript and working with existing tooling is, as I understand it, one of the goals of the Svelte project.

@pngwn
Copy link
Member

pngwn commented Aug 23, 2019

@antony is correct, everything in a Svelte component's script tag has to be syntactically valid javascript. This change is not only invalid but would also be a breaking change.

Whether or not this suggestion is less confusing is entirely subjective because a component doesn't import props it accepts them, control is delegated to the parent, not the other way around. export in this context is closer to "expose an api" than "import a value".

@KieranP
Copy link
Author

KieranP commented Aug 23, 2019

Fair points, but I think a discussion around better semantics is still valid, even if the proposed solution isn't. What about another way of identifying props passed in vs values sent out?

let _name          (though _ tends to be used for unused variables)
let __name         (though __ tends to be internal/framework variables)
let $name          (though $ is used for auto store subscription)
const name         (perhaps might be nice to enforce props passed in can't be changed and therefore don't cause unpredictable behaviour upstream? but still not clear its a prop passed in)
const $_name       (perhaps a nice balance and prevent modification?)

@antony
Copy link
Member

antony commented Aug 23, 2019

Props passed in can be changed, for example a bound prop can mutate. Absolutely happy to have a discussion around it, like you say. The rest of your reasoning is fair - the only workable ones being the underscored ones, and I don't think that really helps imply anything, other than looking quite ugly in my opinion - and yes, it looks like poorly hiding a public variable.

I have to agree with @pngwn though, in that I find the current syntax of export let varName to be the most appropriate, since it describes exactly the sort of behaviour that it creates. Export is something that can be addressed externally, which is what a prop is.

@pngwn
Copy link
Member

pngwn commented Aug 23, 2019

export const name is already a thing for read-only props. export function... is also read-only.

@Rich-Harris
Copy link
Member

I'm going to save everyone's time and close this issue, because I don't see any realistic prospect of this changing. This has been discussed before at considerable length, and export is the best option. It doesn't perfectly match the semantics of export in JavaScript modules, but it's the most appropriate verb since in both contexts 'export' means 'exposing a contract to the outside world', and any replacement would have its own issues.

@paganaye
Copy link

paganaye commented Oct 11, 2020

Import is certainly not an option.
One option that would not break (all) javascript would be to add a prop keyword.

<script>
  prop type;
  prop type;
  prop value;
</script>
<p>
  <label>{label}</label>
  <input type={type} bind:value={value} />
</p>

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

5 participants