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

No way to define required properties (typescript) #1076

Closed
xaviergonz opened this issue Jul 22, 2020 · 15 comments
Closed

No way to define required properties (typescript) #1076

xaviergonz opened this issue Jul 22, 2020 · 15 comments

Comments

@xaviergonz
Copy link

Describe the bug
There's no way currently to define a property as required in typescript.

Logs
N/A

To Reproduce

Test.svelte

<script lang="ts">
  export let reqName: string;
  export let optName: string | undefined;
</script>

<h1>Hello {reqName} {optName || "Doe"}!</h1>

App.svelte

<script lang="ts">
  import Test from "./Test.svelte";
</script>

<main>
  <Test /> <!-- this should complain that reqName is missing -->
</main>

Expected behavior
The compiler should complain that is missing "reqName", since undefined is not a valid value for the exported property.

Stacktraces
N/A

Information about your Svelte project:
Window 10, latest svelte, rollup

Severity
I think not being able to separate required properties from optional ones impacts the ability to do safe refactors. Also, since this would be a breaking change and the official TS support just got released I think it is better to tackle this soon rather than later (or else hide the breaking behaviour under a flag).

@orta
Copy link
Contributor

orta commented Jul 22, 2020

This could be that you need to turn on strict mode in TypeScript

@xaviergonz
Copy link
Author

xaviergonz commented Jul 22, 2020

Thanks for the tip, adding this to tsconfig.json:

  "compilerOptions": {
    "strict": true
  },

and this to Test.svelte

  export let reqName: string;
  export let optName: string | undefined = undefined;

Seems to make it work ok :)

Just wondering, is there a way to specify the type of more complex properties? E.g.

type P = { kind: "A"; foo: boolean } | { kind: "B"; bar: string }

The closest would be this, but is not quite the same:

export let kind: "A" | "B";
export let foo: boolean | undefined = undefined;
export let bar: string | undefined = undefined;

@orta
Copy link
Contributor

orta commented Jul 22, 2020

type P = { kind: "A"; foo: boolean } | { kind: "B"; bar: string }
export let optName: P = { kind: "A", foo: true };

should work

@xaviergonz
Copy link
Author

Sorry, I meant distributed across all properties, not as an object inside a single property

@xaviergonz
Copy link
Author

The closest I got would be this, but is not quite the same:

export let kind: "A" | "B";
export let foo: boolean | undefined = undefined;
export let bar: string | undefined = undefined;

@caroso1222
Copy link
Contributor

I don't think that's possible. Closest would be some sort of discriminated union but won't be applicable at the top level of the component.

@xaviergonz
Copy link
Author

xaviergonz commented Jul 22, 2020

Ah shame, it would be cool if svelte supported an alternate props syntax for these cases. Something like:

<script lang="ts">
  // whenever the "keyword" props is used assume the props in the object are distributed (react-like)
  export let props: { kind: "A"; foo: boolean } | { kind: "B"; bar: string };
</script>

<h1>{props.kind === "A" ? props.foo : props.bar}</h1>
<Test kind="A" foo="x" />

or:

<script lang="ts">
  export let props: { reqName: string; optName?: string }
</script>

<h1>Hello {props.reqName} {props.optName || "Doe"}!</h1>
 <Test reqName="John" />

@dummdidumm
Copy link
Member

Optional props: language-tools issue, see #319 . We are thinking about changing it so it is marked as required in non-strict-mode, too.

Dependencies between props (and slots): currently not supported yet, see #273

@jsdw
Copy link

jsdw commented Oct 9, 2020

I second some of the above. I'm new to Svelte, and coming from React where I can give components generic props and use clever combinations of types and allsorts to define said props, I find myself missing this level of type safety here.

Exposing an "advanced" syntax which lets you define the type of props using the full power of TypeScript would be lovely. Most of the time the "simple" syntax of typing exports is probably good enough, but every now and then we can go advanced and define complex types for our props.

@zimmah
Copy link

zimmah commented Dec 9, 2020

I agree with the above, not just for my own sake, but also to build easier to use component libraries for others to use.

When you have a complex component that requires specific props and has some optional props, it would be nice if as soon as you start typing a component it would tell you which props it expects.

eddiegroves referenced this issue in eddiegroves/bank_locator Feb 6, 2021
The template tsconfig disables strict mode (why??). Enabling strict mode
allows props to be marked as required by Typescript[1].

The strict flag is disabled by default, but TypeScript recommends
enabling it.[2]

"The strict flag enables a wide range of type checking behaviour that
results in stronger guarantees of program correctness. Turning this on
is equivalent to enabling all of the strict mode family options, which
are outlined below. You can then turn off individual strict mode family
checks as needed."

[1]: https://github.com/sveltejs/svelte/issues/5183#issuecomment-662595004
[2]: https://www.typescriptlang.org/tsconfig#strict
@stale
Copy link

stale bot commented Jun 26, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@pngwn pngwn transferred this issue from sveltejs/svelte Jun 26, 2021
@dummdidumm
Copy link
Member

With the latest version of the Svelte for VS Code extension and svelte-check props are marked as required if not initialized. For generics see #442

@Lootwig
Copy link

Lootwig commented Jun 28, 2022

Is this IDE specific? typescript strict mode is turned on for me, but I do not get any warnings/errors regarding required props inside IntelliJ or in npm run dev's output.

@gianmarco27
Copy link

Same for me

@dummdidumm
Copy link
Member

The intellij plugin is independent of this and maintained by someone else. npm run dev won't show any errors, use the svelte-check npm package for this

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

8 participants