preactjs / preact-router

:earth_americas: URL router for Preact.
http://npm.im/preact-router
MIT License
1.01k stars 156 forks source link

bug: type conflict in preact-router after preactjs/preact#3747 #432

Open motss opened 1 year ago

motss commented 1 year ago

Describe the bug

Encountering the following TypeScript error with the latest Preact 10.11.1 that supports SignalLike<T> type:

error TS2430: Interface 'HTMLAttributes<RefType>' incorrectly extends interface 'ClassAttributes<RefType>'.
  Types of property 'default' are incompatible.
    Type 'boolean | SignalLike<boolean> | undefined' is not assignable to type 'boolean | undefined'.
      Type 'SignalLike<boolean>' is not assignable to type 'boolean | undefined'.

671  export interface HTMLAttributes<RefType extends EventTarget = EventTarget>
                      ~~~~~~~~~~~~~~

Found 1 error in node_modules/preact/src/jsx.d.ts:671

Upon investigation, the error was caused by RoutableProps which is documented here in preact-router when skipLibCheck: true in tsconfig.json.

To Reproduce

Pre-requisites:

  1. dependencies:preact@10.11.1, preact-router@4.1.0
  2. devDependencies: typescript@4.8.4

Steps to reproduce the behavior:

  1. Run npm create vite@latest my-vue-app -- --template preact-ts
  2. Run npm i preact@10.11.1 preact-router@4.1.0
  3. Run npm i -D typescript@4.8.4
  4. Set skipLibCheck: false in tsconfig.json
  5. Add the following code in app.tsx:
    <Router>
      <div />
    </Router>
  6. See error

Expected behavior

RoutableProps which is documented here should be updated to follow the same typing as HTMLAttributes['default'] which supports Preact signals.

Possible solution(s)

  1. Update the type of RoutableProps['default'] to support SignalLike because it is a prop of Router that can possibly accept a signal value:
    export interface RoutableProps extends Pick<HTMLAttributes<HTMLElement>, 'default'> {
      path?: string;
    }
  2. Introduce new prop to avoid type conflict with HTML default attribute, such as defaultRoute