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

Astro.props is type as any when use Polymorphic #10347

Closed
1 task
RodrigoTomeES opened this issue Mar 6, 2024 · 9 comments
Closed
1 task

Astro.props is type as any when use Polymorphic #10347

RodrigoTomeES opened this issue Mar 6, 2024 · 9 comments
Labels
feat: typescript Related to TypeScript (scope) needs discussion Issue needs to be discussed

Comments

@RodrigoTomeES
Copy link

Astro Info

Astro                    v4.4.13
Node                     v20.9.0
System                   Windows (x64)
Package Manager          pnpm
Output                   hybrid
Adapter                  @astrojs/vercel/serverless
Integrations             @astrojs/tailwind

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

Astro.props is type as any

image

---
import type { HTMLTag, Polymorphic } from "astro/types"

type Props<Tag extends HTMLTag> = Polymorphic<{
	as: Tag
	variant: keyof typeof variantClasses
	color: keyof typeof colorClasses
}>

const { as: Tag, class: className, variant, color, ...props } = Astro.props

const variantClasses = {
	h2: "text-lg font-medium uppercase lg:text-2xl",
	h3: "text-2xl font-semibold uppercase",
	body: "text-xl",
	medium: "text-md",
}

const colorClasses = {
	white: "text-white",
	black: "text-black",
	primary: "text-accent",
	neutral: "text-neutral-300",
}

const classes = [
	variantClasses[variant as keyof typeof variantClasses],
	colorClasses[color as keyof typeof colorClasses],
	className,
]
---

<Tag class:list={classes} {...props}>
	<slot />
</Tag>

What's the expected result?

That has the types of Props.

In the codesandbox the error not appear but try it in vscode and it will appear

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-yq21np?file=tsconfig.json,src%2Fpages%2Findex.astro

Participation

  • I am willing to submit a pull request for this issue.
@Princesseuh
Copy link
Member

I suspect that this is a compiler issue, most likely related to withastro/compiler#927 in some ways

@lilnasy
Copy link
Contributor

lilnasy commented Mar 6, 2024

Maybe we need to document that Props needs default values when it is a generic.

-type Props<Tag extends HTMLTag> = Polymorphic<{
+type Props<Tag extends HTMLTag = HTMLTag> = Polymorphic<{
	as: Tag
	variant: keyof typeof variantClasses
	color: keyof typeof colorClasses
}>

@lilnasy lilnasy added needs discussion Issue needs to be discussed feat: typescript Related to TypeScript (scope) and removed needs triage Issue needs to be triaged labels Mar 6, 2024
@RodrigoTomeES
Copy link
Author

Maybe we need to document that Props needs default values when it is a generic.

-type Props<Tag extends HTMLTag> = Polymorphic<{
+type Props<Tag extends HTMLTag = HTMLTag> = Polymorphic<{
	as: Tag
	variant: keyof typeof variantClasses
	color: keyof typeof colorClasses
}>

The documentation doesn't mention anything about requiring a default value. 🤔

https://docs.astro.build/en/guides/typescript/#polymorphic-type

@lilnasy
Copy link
Contributor

lilnasy commented Mar 6, 2024

I should clarify, I meant that we should mention it.

@RodrigoTomeES
Copy link
Author

I should clarify, I meant that we should mention it.

I tried this solution but now I have this error:
Screenshot 2024-03-07 at 12 16 10

@Eveeifyeve
Copy link

I felt this would be a cool idea cause it will help devs with type safety.

@nasheomirro
Copy link

nasheomirro commented Mar 12, 2024

I tried this solution but now I have this error: Screenshot 2024-03-07 at 12 16 10

try adding a default value for the tag as well. I'm not sure what changed but it seems the Polymorphic type now makes as optional, correct me if I'm wrong but I remember the previous behavior was that the component requires you to always provide an as prop.

Edit: In addition to adding a default value, you need to cast it with any as well, just the easiest work-around I've found so far:

---
import type { Polymorphic, HTMLTag } from "astro/types";

type Props<T extends HTMLTag = HTMLTag> = Polymorphic<{ as: T }>;
const { as: Tag = "div" as any, ...attrs } = Astro.props;
---

<Tag {...attrs}>
  <slot />
</Tag>

@RodrigoTomeES
Copy link
Author

I tried this solution but now I have this error: Screenshot 2024-03-07 at 12 16 10

try adding a default value for the tag as well. I'm not sure what changed but it seems the Polymorphic type now makes as optional, correct me if I'm wrong but I remember the previous behavior was that the component requires you to always provide an as prop.

Edit: In addition to adding a default value, you need to cast it with any as well, just the easiest work-around I've found so far:

---
import type { Polymorphic, HTMLTag } from "astro/types";

type Props<T extends HTMLTag = HTMLTag> = Polymorphic<{ as: T }>;
const { as: Tag = "div" as any, ...attrs } = Astro.props;
---

<Tag {...attrs}>
  <slot />
</Tag>

You are right, with the default value as is optional

@matthewp
Copy link
Contributor

Not providing a type argument default is an error. You can see this by assigning a variable to the type like so:

Screen Shot 2024-05-13 at 3 23 47 PM

Since your type has an error then Astro.props cannot be declared as that type, which is why it's showing as any. Closing as there's nothing that can be done here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: typescript Related to TypeScript (scope) needs discussion Issue needs to be discussed
Projects
None yet
Development

No branches or pull requests

6 participants