Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Question: Typescript narrowing between script and "HTML" #13

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

Closed
jamesshannon opened this issue Mar 23, 2023 · 1 comment
Closed

Question: Typescript narrowing between script and "HTML" #13

jamesshannon opened this issue Mar 23, 2023 · 1 comment

Comments

@jamesshannon
Copy link

Trying to figure something out and I found your documentation but it doesn't address my question. So I was hoping you could answer it and maybe update the docs.

I'm trying to narrow down a variable. My IDE (VS Code) understands that the variable is narrowed in the script (<script lang="ts">) but not in the "HTML" code outside of the script. Basically, I'm doing this inside of a component:

<script lang="ts">
// creating this as undefined so that the component can be created without passing in partner
export let partner: Partner | undefined = undefined;

if (! partner) {
  partner = new Partner();
}
</script>

<span>{ partner.id }</span>

Inside of the script, after the if block, typescript accurately understands that partner is now Partner.

However, I get an error within the -- partner: Partner | undefined -- 'partner' is possibly 'undefined'.

My expectation is that since Partner has been narrowed at the end of the script block it'll be narrowed within the HTML as well.

Am I doing something wrong? Is there a workaround?

@ivanhofer
Copy link
Owner

You could create a new issue in the https://github.com/sveltejs/language-tools/ repo.

What I usually do when a type does not match is to create a function that casts the type. SOmething like this:

<script lang="ts">
	export let partner: Partner | undefined = undefined;

	if (!partner) {
		partner = new Partner();
	}

+	const castPartner = (partner: Partner | undefined) => partner as Partner
</script>

-<span>{ partner.id }</span>
+<span>{ castPartner(partner).id }</span>

Or in your specific case you don't need a cast at all:

<script lang="ts">
-	export let partner: Partner | undefined = undefined;
+	export let partner: Partner = new Partner();

-	if (!partner) {
-		partner = new Partner();
-	}
</script>

<span>{ partner.id }</span>

You can also create an internal representation of that param:

<script lang="ts">
	export let partner: Partner | undefined = undefined;

+	$: _partner = partner || new Partner();
</script>

-<span>{ partner.id }</span>
+<span>{ _partner.id }</span>

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

2 participants