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

createEventHook listener/trigger types aren't inferred properly #3565

Closed
7 tasks done
romansp opened this issue Nov 17, 2023 · 1 comment · Fixed by #3569
Closed
7 tasks done

createEventHook listener/trigger types aren't inferred properly #3565

romansp opened this issue Nov 17, 2023 · 1 comment · Fixed by #3569

Comments

@romansp
Copy link
Contributor

romansp commented Nov 17, 2023

Describe the bug

There's a types inference regression introduced by #3507 for createEventHook listeners/triggers.

Previously arguments in on listeners would be correctly inferred from the type argument of createEventHook function. Today it will resolve to any when type argument is a union type. For projects with noImplicitAny enabled it now triggers an error.

It's also possible to omit arguments for trigger completely even though createEventHook was declared with a single type argument. See provided TS playground links.

Using typescript v5.2.2.

// 10.5.0
const numberOrStringHook = createEventHook<number | string>();
numberOrStringHook.on(value => {
  // value: number | string
});

// error: Expected 1 arguments, but got 0.
numberOrStringHook.trigger();

playground link

// 10.6.1
const numberOrStringHook = createEventHook<number | string>();
numberOrStringHook.on(value => {
  // value: any
});

// no errors
numberOrStringHook.trigger();

playground link

It also affected useFileDialog.onChange

import { useFileDialog } from "@vueuse/core";

const { onChange } = useFileDialog();
onChange(files => {
  // files is `any` but used to be `FileList | null`
});

playground link

Reproduction

https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgYygUwIYzQUQG5oB2MAEhBANZwC+cAZlBCHAEQACeArmpwM5oB6XgAsM6ACYsA3HAEC4MAJ5g0vAFxwAjAAYAdADZdmgLAAoM8giFe8QpxAAjNFDKU4AXhTosuAsVcUADx2js4AfAAUAJRSZiFOLuQUulYREXgYADbcUR5hiGZwRcUlpbICAHoA-GbUUWZx9gkBujBQwADmHc4RmjGNoYmUre1dPSw27YQdLP2m8c4tbZ3dUNGx802LSSMrPQh1GxZWNnALUADyUADKy9MBHl6Y2PhEpEnBW1BwAD5wk8BppE5ucrrcph0Wql0lkcnkCqYykjkeVqrV6uZNoMwXdITtlmM1n0NqCbrilqNVhEJrjZiSvjiIRS9msQQyyUz8ZT9ocGpjLNZ4HgIMBxA9PKhnr43gF1mZhaKoYQ0hlsmhcu58ghCiiinI0aY6nyFWKuSzenMTczCdSAdM6fKRabhgSqZandaqQc5kA

System Info

System:
    OS: macOS 14.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 215.66 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.18.2 - /usr/local/bin/node
    Yarn: 4.0.1 - /opt/homebrew/bin/yarn
    npm: 9.8.1 - /usr/local/bin/npm
    bun: 1.0.6 - ~/.bun/bin/bun
  Browsers:
    Chrome: 119.0.6045.159
    Safari: 17.1
  npmPackages:
    @vueuse/components: ^10.6.1 => 10.6.1 
    @vueuse/core: ^10.6.1 => 10.6.1 
    @vueuse/integrations: ^10.6.1 => 10.6.1 
    vue: ^3.3.8 => 3.3.8

Used Package Manager

yarn

Validations

@kirk-loretz-fsn
Copy link

The type inference regression for useFileDialog.onChange is due to distributive conditional types.

onChange: EventHookOn<FileList | null>

type Callback<T> = T extends void ? () => void : (param: T) => void
export type EventHookOn<T = any> = (fn: Callback<T>) => { off: () => void }

Changing the Callback type to this would help fix useFileDialog.onChange:

type Callback<T> = [T] extends [void] ? () => void : (param: T) => void

Typescript Playground

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

Successfully merging a pull request may close this issue.

2 participants