preactjs/preact-iso

Type 'Element' is not assignable to type 'VNode<{}>[]'

Closed this issue · 8 comments

Hi, I'm receiving errors like:

src/app.tsx:47:13 - error TS2322: Type 'Element' is not assignable to type 'VNode<{}>[]'.

47             <Route path='/' component={Home} />
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  node_modules/preact-iso/src/router.d.ts:9:2
    9  children?: VNode[];
       ~~~~~~~~
    The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & { onRouteChange?: ((url: string) => void) | undefined; onLoadEnd?: ((url: string) => void) | undefined; onLoadStart?: ((url: string) => void) | undefined; children?: VNode<...>[] | undefined; }'

src/app.tsx:47:13 - error TS2322: Type 'Element' is not assignable to type 'VNode<{}>[]'.

47             <Route path='/' component={Home} />
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  node_modules/preact-iso/src/router.d.ts:9:2
    9  children?: VNode[];
       ~~~~~~~~
    The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & { onRouteChange?: ((url: string) => void) | undefined; onLoadEnd?: ((url: string) => void) | undefined; onLoadStart?: ((url: string) => void) | undefined; children?: VNode<...>[] | undefined; }'

I've search for something similar and stumble upon these:

I tried:

I'm using this template: https://github.com/bluwy/create-vite-extra/tree/master/template-ssr-preact-ts

Nothing has changed, except that I installed react-iso and tried to copy the last router example: Nested Routing.

BTW, in this example, the <ErrorBoundary> from "Profile" component is missing "/".

This is my tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,
    "paths": {
      "react": ["./node_modules/preact/compat/"],
      "react-dom": ["./node_modules/preact/compat/"]
    },

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "jsxImportSource": "preact",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

And my package.json:

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "node server",
    "build": "npm run build:client && npm run build:server",
    "build:client": "vite build --ssrManifest --outDir dist/client",
    "build:server": "vite build --ssr src/entry-server.tsx --outDir dist/server",
    "generate": "vite build --outDir src/static && npm run build:server && node prerender.js",
    "preview": "cross-env NODE_ENV=production node server"
  },
  "dependencies": {
    "preact": "^10.19.3",
    "preact-iso": "^2.3.2",
    "preact-render-to-string": "^6.3.1"
  },
  "devDependencies": {
    "@preact/preset-vite": "^2.6.0",
    "@types/express": "^4.17.21",
    "@types/node": "^20.9.0",
    "compression": "^1.7.4",
    "cross-env": "^7.0.3",
    "express": "^4.18.2",
    "sirv": "^2.0.3",
    "typescript": "^5.2.2",
    "vite": "^5.0.0"
  }
}

I'm going to move to https://github.com/preactjs/preact-router for now and see if it works.

Please provide a reproduction that can be cloned and ran.

If we have to guess what you've written we may not be able to address the issue properly.

Edit:

BTW, in this example, the from "Profile" component is missing "/".

Cheers, fixed.

@rschristian, I was providing the example repository, and then I took another look at the error:

src/pages/Profile.tsx:30:9 - error TS2740: Type 'VNode<any>' is missing the following properties from type 'VNode<{}>[]': length, pop, push, concat, and 29 more.

30         <Route path="/profiles/*" component={Profile} />
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  node_modules/preact-iso/src/router.d.ts:9:2
    9  children?: VNode[];
       ~~~~~~~~
    The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & { onRouteChange?: ((url: string) => void) | undefined; onLoadEnd?: ((url: string) => void) | undefined; onLoadStart?: ((url: string) => void) | undefined; children?: VNode<...>[] | undefined; }'

There's a hint at: type 'VNode<{}>[]': length, pop, push, concat, and 29 more..

I changed from single child to multiple, like so:

Before

grafik

After

grafik

It seems that <Router> expects children and not a single child. Not sure if it's expected behaviour.

In any case, I have set up an example here: https://github.com/RickStanley/poc-ssg-preact/blob/sample/src/pages/Profile.tsx

git clone https://github.com/RickStanley/poc-ssg-preact/ -b sample

It seems that <Router> expects children and not a single child. Not sure if it's expected behaviour

Yes, a router with only a single route is entirely redundant.

Got it. I'm, at this time, experimenting with only one route, I thought it was a bug. Thanks for clarifying.

No worries -- types are used to discourage this as a router is going to have a lot more overhead than a typical conditional rendering approach for a single route.

Just to point out: I copied from the example Nested Routing, in this example there's only one route, so, anyone copying and pasting this example will be met with the same error, but as you've said, "a router with only a single route is entirely redundant."

It may not be so obvious for people trying this out, like me.

Ah shoot, that we do. Will fix, thanks.