language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

the contructor's `props` should be required if they contain a required prop

Open ivanhofer opened this issue 2 years ago • 4 comments

I have updated the description

Description

When using the JavaScript API to instantiate a Svelte component, I would find it useful to get an error if I forget to pass props.

image

In this case the Component has a required prop called title that expects a string. I can completely omit the props attribute and won't get an error.

Proposed solution

Type the params object of the ComponentConstructorOptions to get errors when instantiating a component incorrectly.

Alternatives

No response

Additional Information, eg. Screenshots

No response

ivanhofer avatar Aug 07 '22 18:08 ivanhofer

Can you give a reproducible? Not sure what exactly is going on there.

dummdidumm avatar Aug 08 '22 07:08 dummdidumm

Sorry, I thought this is a general issue since I never saw it working.

I tried to create a fresh repo but cannot reproduce it there. Then I have deleted my node_modules folder and installed all dependencies again and now it works there too. It was a project that was living on my laptop a few months and I did a couple of npm updates. Maybe something broke there. But still weird..

The props are typed correctly.

Anyhow, I still don't get an error if I don't set the props attribute at all. https://stackblitz.com/edit/vitejs-vite-regq6z?file=src/main.ts I would expect to get an error there.

I was thinking about having type definitions like this:


interface ComponentConstructorOptionsWithoutProps {
	target: Element | ShadowRoot;
	anchor?: Element;
	context?: Map<any, any>;
	hydrate?: boolean;
	intro?: boolean;
	$$inline?: boolean;
}

interface ComponentConstructorOptionsWithProps<Props extends Record<string, any> = Record<string, any>> extends ComponentConstructorOptionsWithoutProps {
	props: Props;
}

type ComponentConstructorOptions<Props extends Record<string, any> | never = never> = Props extends never
	? ComponentConstructorOptionsWithoutProps
	: ComponentConstructorOptionsWithProps<Props>;

ivanhofer avatar Aug 08 '22 11:08 ivanhofer

Mhm right, the props not set at all issue is a bummer. It's the type definitions that need to be enhanced here, although that's probably more on the Svelte typings itself, and since it's a breaking change that's a v4 thing. We could add similar typings to the existing shims though (it would be breaking there, too, but with the new transformation incoming we need to do one anyway).

dummdidumm avatar Aug 08 '22 12:08 dummdidumm

Yes I was also assuming that this would be a breaking change. Not sure if I understood it correctly but the language tools could "patch" the types without the Svelte-typings to change right?

Ah, and what I forgot in the example above is the following type:

interface ComponentConstructorOptionsWithOptionalProps<Props extends Record<string, any> = Record<string, any>> extends ComponentConstructorOptionsWithoutProps {
	props?: Props;
}

So in the end there should be three cases:

  • component has no props
  • component has only optional props
  • component has at least one required prop

ivanhofer avatar Aug 08 '22 12:08 ivanhofer