Skip to content

Support TypeScript generics on snippets #15883

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

Open
WarningImHack3r opened this issue May 8, 2025 · 5 comments
Open

Support TypeScript generics on snippets #15883

WarningImHack3r opened this issue May 8, 2025 · 5 comments

Comments

@WarningImHack3r
Copy link

Describe the problem

I just noticed it's not possible to use generics in a raw snippet declaration:

{#snippet mySnippet<T extends { prop: string }>(item: T)}
    <div>{item.prop}</div>
{/snippet}

Is it intentional? Is such a feature expected to be supported in the future? Snippets passed as props do support generics, so I think this should be added, in my opinion.

Describe the proposed solution

Add full TypeScript support for snippets in the markup

Importance

nice to have

@jhwz
Copy link
Contributor

jhwz commented May 8, 2025

What's the use case for generics in snippets?

Your example should just be:

{#snippet mySnippet(item: { prop: string })}
    <div>{item.prop}</div>
{/snippet}

Generics doesn't do anything there 🙂

@WarningImHack3r

This comment has been minimized.

@jhwz
Copy link
Contributor

jhwz commented May 8, 2025

Generics are usually useful for tying the type of a function argument with the type of the function return. Because snippets don't "return" anything in theory it shouldn't be needed, but there may be situations I'm missing. In that case you would just do:

{#snippet mySnippet(item: Parent, str: string)}
	<span>{item.someCommonProp}</span>
	<div>{str}</div>
{/snippet}

{@render mySnippet(a, `hi from A: ${item.aSpecificProp}`)}
{@render mySnippet(b, `hi from B: ${item.bSpecificProp}`)}

i.e. you resolve the field access outside of the snippet

@WarningImHack3r
Copy link
Author

My bad again! I gave another look at my code and it's more complicated than that; my argument is an array:

<script lang="ts">
	type Parent = A | B; // A and B have common properties as well as some unique ones, `Parent` is here used to get easily the common ones

	const a: A;
	const b: B;
</script>

{#snippet mySnippet<T extends Parent>(items: T[], strFromItem: (item: T) => string)}
	<span>{item.someCommonProp}</span>
	{#each items as item}
		<!-- `strFromItem` allows here to access the specific properties of the passed item without needing to know about them, hence the `T extends Parent` -->
		<!-- there might be better ways to achieve this, I'm not a TS wizard, but I think it's enough to get the usefulness of generic snippets -->
		<div>{strFromItem(item)}</div>
	{/each}
{/snippet}

{@render mySnippet(a, item => `hi from A: ${item.aSpecificProp}`)}
{@render mySnippet(b, item => `hi from B: ${item.bSpecificProp}`)}

@jhwz
Copy link
Contributor

jhwz commented May 8, 2025

My bad again! I gave another look at my code and it's more complicated than that; my argument is an array:

Ah that makes sense! I didn't think of that case

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