Description
[this is now the feedback thread]
This was implemented according to this RFC. Please provide feedback about using it in this thread.
Original Post
There are several issues about this already (#424, sveltejs/svelte#304, sveltejs/svelte#273, sveltejs/svelte#263), but I wanted to make a consolidated one to have a discussion about the approaches we can take.
Related PR: sveltejs/svelte#437
Note that this issue is NOT about typing a d.ts
file, this will come afterwards as a separate issue.
Is your feature request related to a problem? Please describe.
At the moment it is not possible to type the inputs/outputs of a component under certain circumstances:
- It is not possible to define a generic relationship between props and events/slots (generics)
- It is not possible to define the events and their types
- It is not possible to define the slots and their types in a specific way
Describe the solution you'd like
A way to type props/events/slots explicitly.
Proposal: A new reserved interface ComponentDef
which, when defined, is used as the public API of the component instead of infering the things from the code.
Example (with comments about what likely is not possible):
<script lang="ts"
interface ComponentDef<T> { // <-- note that we can use generics as long as they are "defined" through props
props: { items: T[] }
events: { itemClick: CustomEvent<T> }
slots: { default: { item: T } }
}
// generic type T is not usable here. Is that a good solution? Should it be possible?
// Also: How do we make sure the types match the component definition?
export items: any[];
// ...
// We cannot make sure that the dispatched event and its type are correct. Is that a problem?
// Maybe enhance the type definitions in the core repo so createEventDispatcher accepts a record of eventname->type?
dispatch('itemClick', item);
</script>
<!-- ... -->
<slot item={item}> <!-- again, we cannot make sure this actually matches the type definition -->
When someone now uses the component, he will get the correct types from the props/events/slots and also error diagnostics when something is wrong:
<Child
items="{['a', 'string']}"
on:itemClick="{event => event.detail === 1 /* ERROR, number not comparable to type string */}"
/>
If this works and is tested a little, we could enhance it with other reserved interfaces like ComponentEvents
to only type one of the things.
I'd like to get as much feedback on this as possible because this is likely a big change which might be used broadly. Also, I'd like to have some of the core team members to have a look at this if this looks good to them or introduces something they don't agree with.