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

IntrinsicAttributes and HTMLAttributes have conflicts #11072

Closed
1 task done
duckycoding-dev opened this issue May 16, 2024 · 3 comments · Fixed by #11092
Closed
1 task done

IntrinsicAttributes and HTMLAttributes have conflicts #11072

duckycoding-dev opened this issue May 16, 2024 · 3 comments · Fixed by #11092
Labels
- P2: nice to have Not breaking anything but nice to have (priority)

Comments

@duckycoding-dev
Copy link
Contributor

duckycoding-dev commented May 16, 2024

Astro Info

Astro                    v4.8.4
Node                     v21.6.2
System                   macOS (x64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/mdx
                         astro:db
                         @astrojs/db/file-url
                         @astrojs/tailwind

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

No response

Describe the Bug

astroHTML.JSX.IntrinsicAttributes and HTMLAttributes conflicting type definitions (I found one at least):

astroHTML.JSX.IntrinsicAttributes {
...
    slot: string | undefined
...
}

HTMLAttributes{
...
    slot: string | undefined | null
...
}

If I were to define for two components MyComponent and MyComponentWrapper a Props interface extending from HTMLAttributes<'div'> for example, I can't forward props to MyComponent by spreading the props received by MyComponentWrapper, even tho they should be of the same type: I get the error "Type { .... } is not assignable to type 'IntrinsicAttributes & Props'. "

Error on local machine but not on StackBlitz example, please try it locally by using the example provided inside StackBlitz; I get the same error both on Windows (WSL) and MacOS:

Type '{ children: any; class: string; 'class:list'?: string | Record<string, boolean> | Record<any, any> | Iterable<string> | Iterable<any> | undefined; ... 187 more ...; onfullscreenerror?: string | ... 1 more ... | undefined; }' is not assignable to type 'IntrinsicAttributes & Props'.
  Type '{ children: any; class: string; 'class:list'?: string | Record<string, boolean> | Record<any, any> | Iterable<string> | Iterable<any> | undefined; ... 187 more ...; onfullscreenerror?: string | ... 1 more ... | undefined; }' is not assignable to type 'IntrinsicAttributes'.ts(2322)

// this gives error, most likely because of the type difference of slot between IntrinsicAttributes and HTMLAttributes
---
interface Props extends HTMLAttributes<'html'>{};
const props = Astro.props;
---

<MyComponent {...props}> 
...


// by guarding from slot equal to null the error goes away indeed
---
interface Props extends HTMLAttributes<'html'>{};
const props = Astro.props;
const slot = props.slot || undefined // type of slot is then string | undefined
---

<MyComponent {...props} slot={cleanedSlot}> 
...


// or even like this, but this removes the slot prop altogether
---
interface Props extends HTMLAttributes<'html'>{};
const {slot, ...props} = Astro.props;
---

<MyComponent {...props}> 
...

What's the expected result?

I would expect HTMLAttributes and IntrinsicAttributes to not have conflicting definitions, if I'm not missing something, else I would have to always type guard the slot attribute every time I extend from HTMLAttributes and pass props to another component whose Props interface also extends from HTMLAttributes

Link to Minimal Reproducible Example

https://stackblitz.com/edit/withastro-astro-qnckaa?file=src%2Flayouts%2FDivWrapper.astro

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label May 16, 2024
@duckycoding-dev
Copy link
Contributor Author

duckycoding-dev commented May 17, 2024

My solution would be adding "null" to the possible types of slot inside the IntrinsicAttributes interface declared in astro/astro-jsx.d.ts

declare namespace astroHTML.JSX {
	export type Child = Node | Node[] | string | number | boolean | null | undefined | unknown;
	export type Children = Child | Child[];

	interface ElementChildrenAttribute {
		// eslint-disable-next-line @typescript-eslint/ban-types
		children: {};
	}

	interface IntrinsicAttributes
		extends AstroBuiltinProps,
			AstroBuiltinAttributes,
			AstroClientDirectives {
		slot?: string | null;    // <===========================LIKE THIS
		children?: Children;
	}

Though, I'm not sure if there was a specific reason for this to be of type string | undefined without null, while HTMLAttributes has all its attributes of type string | undefined | null.

@Princesseuh
Copy link
Member

It seems fine to me to add undefined! If you're interested in sending a PR for it, we'd gladly accept it.

@duckycoding-dev
Copy link
Contributor Author

It seems fine to me to add undefined!

You mean "to add null" to IntrinsicAttributesright? Since that's the one type missing (because slot is defined using ?) ^-^''
But yes, I will send the PR later today! (I'll take some time to read the "how-to" first though ^^)

@matthewp matthewp added - P2: nice to have Not breaking anything but nice to have (priority) and removed needs triage Issue needs to be triaged labels May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P2: nice to have Not breaking anything but nice to have (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants