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(writer)!: use type alias instead of interface for RestProps #138

Merged
merged 7 commits into from
Oct 27, 2024

Conversation

metonym
Copy link
Collaborator

@metonym metonym commented Oct 25, 2024

Fixes #137

Currently, Sveld creates an Interface type for component props. If the component has RestProps, the interface will extend it. For most cases, this works fine.

type RestProps = SvelteHTMLElements["button"];

export interface ComponentProps extends RestProps { /** ... */ }

However, this can cause a TypeScript error if component props incorrectly extends RestProps.

A very simple example:

type RestProps = SvelteHTMLElements["a"];

export interface ComponentProps extends RestProps {
  tabindex?: string;
}

A TypeScript error occurs because the tabindex on the ComponentProps incorrectly extends that on SvelteHTMLElements["a"] (tabindex can be string | number).

The correct approach would be to use a type alias for the generated component props type.

Note, however, that the below example will result in a TypeScript error for the consumer. This is because tabindex already exists on SvelteHTMLElements["a"] and incorrectly extends the type (string | number vs. string).

type RestProps = SvelteHTMLElements["a"];

export type ComponentProps = RestProps & {
  tabindex?: string;
}

// If using ComponentProps, a TypeScript Error can still occur: Type <X> is not assignable to type 'never'.

The last step is to omit the keys from the component props from RestProps.

type RestProps = SvelteHTMLElements["a"];

type $Props = {
  tabindex?: string;
}

export type ComponentProps = Omit<RestProps, keyof $Props> & $Props;

In summary:

  • RestProps can be an intersection of multiple SvelteHTMLElements.
  • Create a separate, internal type for component props.
  • Create an intersection of RestProps and $Props where keys from $Props are omitted from RestProps.

This is considered a breaking change since the generated component type is exported from the type file.

@metonym metonym changed the title Use type alias instead of interface for RestProps fix(writer)!: use type alias instead of interface for RestProps Oct 25, 2024
@metonym metonym force-pushed the use-type-alias-for-rest branch from b51e91f to 964d895 Compare October 25, 2024 19:04
@metonym metonym force-pushed the use-type-alias-for-rest branch from 964d895 to 8be5109 Compare October 25, 2024 19:14
@metonym metonym force-pushed the use-type-alias-for-rest branch 3 times, most recently from a3190af to 71e7e89 Compare October 25, 2024 22:18
@metonym metonym force-pushed the use-type-alias-for-rest branch from 71e7e89 to 87f926f Compare October 27, 2024 21:50
@metonym metonym force-pushed the use-type-alias-for-rest branch from 87f926f to 243fc23 Compare October 27, 2024 21:53
@metonym metonym merged commit d9cf04a into main Oct 27, 2024
4 checks passed
@metonym metonym deleted the use-type-alias-for-rest branch October 27, 2024 22:02
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

Successfully merging this pull request may close these issues.

TypeScript error when extending multiple RestProps
1 participant