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

FunctionComponent should allow returning VNode[] for HTM #3893

Closed
1 task
reinhrst opened this issue Feb 12, 2023 · 6 comments
Closed
1 task

FunctionComponent should allow returning VNode[] for HTM #3893

reinhrst opened this issue Feb 12, 2023 · 6 comments
Labels

Comments

@reinhrst
Copy link

reinhrst commented Feb 12, 2023

  • Check if updating to the latest Preact version resolves the issue

Describe the bug
Trying to use typing (tsserver with JSDoc), with Preact/HTM, I get a type-mismatch when I try to annotate my Function Components:

Type '() => VNode<any> | VNode<any>[]' is not assignable to type 'FunctionComponent<{}>'.
  Type 'VNode<any> | VNode<any>[]' is not assignable to type 'VNode<any>'.
     Type 'VNode<any>[]' is missing the following properties from type 'VNode<any>': type, props, key (tsserver 2322)

To Reproduce

import { h, render } from 'preact'
import htm from 'htm'
const html = htm.bind(h);

/**
 * @template P
 * @typedef {import('preact').FunctionComponent<P>} FunctionComponent<P>
 */
/** @type {FunctionComponent<{}>} */
const App = () => {    // <-- tsserver gives the error on this line
  return html`<div />`
}

tsconfig.json

{
  "compilerOptions": {
    "module": "es6",
    "checkJs": true,
    "target": "ES6",
    "noEmit": true
  }
}

Expected behavior
Obviously no tsserver error.

I think that FunctionComponent is expecting jsx components (which only ever return a single parent node; whereas HTM can return an array of VNode's).

@reinhrst
Copy link
Author

And just to be clear, I get the same behaviour using:

import { h, FunctionComponent, render } from 'preact'
import htm from 'htm'
const html = htm.bind(h);

/** @type {FunctionComponent<{}>} */
const App = () => {    // <-- tsserver gives the error on this line
  return html`<div />`
}

@rschristian
Copy link
Member

As FunctionComponent generally shouldn't be used anyhow (lots of articles out there stating the issues it has), and htm being a somewhat niche option with fairly different semantics due to a lack of JSX, I don't think this should be supported. It'll only cause confusion for the majority who use JSX.

@rschristian rschristian closed this as not planned Won't fix, can't repro, duplicate, stale Apr 19, 2024
@reinhrst
Copy link
Author

@rschristian Can you link to articles describing why FunctionComponent should not be used (ideally with examples of what I should be using instead)?

As of today, the preact typescript documentation has examples with FunctionComponent.

I understand htm being used only by a minority, but it would be great if a simple "hello world" would be possible without giving a typescript error (possibly by adding something to the docs on how to do it correctly).

@rschristian
Copy link
Member

rschristian commented Apr 19, 2024

Can you link to articles describing why FunctionComponent should not be used (ideally with examples of what I should be using instead)?

Check the "Why is React.FC not needed?" section here. It's an anti-pattern and has been for a few years now. Use type inference, there's absolutely no need to explicitly type components.

As of today, the preact typescript documentation has examples with FunctionComponent.

The TS docs on the Preact site are pretty out of date and rough unfortunately, and not a priority for me to fix at the moment. I wouldn't recommend you type events as it suggests either.

@reinhrst
Copy link
Author

Thanks, that makes sense!

Would you accept a PR for the typescript documentation page (I should have some time to update that in the next couple of weeks), or is this part of a larger operation to be doen later?

@rschristian
Copy link
Member

PRs definitely welcome, as far as I am aware there are no plans for future content changes (beyond maybe preactjs/preact-www#1098).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants