For me `f1` looks correct. You expect a function for which you say the parameter is of an unknown type, so parsing it as number is not valid - you could call the provided function with any value not just a number. But that TypeScript accepts `f3` is really weird (a bug?).
Alternatively, you can use generics to automatically infer the type (which of course can lead to other problems if the main function already uses generics). If you would ever call the passed function (I guess you don't in your use case?) you would have to ensure that the value is of type `T`.
```
declare function f4<T>(fn: (x: T) => void): void;
```
Daishi KatoCreator
`f3` is called bivariant hack. Actually, `f4` works for my case! I'll open a PR in the Jotai repo.
3851521714694
Ah, never heard of that. But good to know, thanks.
Martin Winkler
This might help solve a current problem of mine; do you have any idea if I could use a generic when my function must accomodate any number of arguments?
What I have currently:
```js
export const usePreparedAsync = <TResult, TError>(
asyncFunc: (...args: unknown[]) => Promise<TResult>
): ReturnPrepared<TResult, TError> => {
// ...some state setup...
const run = async (...args: unknown[]) => {
// ...
await asyncFunc(...args).then(...)
// ...
return {
aborted: unmountController.signal.aborted,
result: resolvedValue,
} as ResultPrepared<TResult>
}
return { run, isRunning, result, error }
}
```
When I try to replace `unknown[]` with a generic type...
```
const usePreparedAsync = <TResult, TError, TArgs = unknown[]>(
asyncFunc: (...args: TArgs) => Promise<TResult>,
)
```
...I get a warning:
A rest parameter must be of an array type.ts(2370)
(parameter) args: TArgs
3851521714694
It should work if you define that `TArgs` must be an array:
```
usePreparedAsync = <TResult, TError, TArgs extends unknown[] = unknown[]>
```
5 comments
For me `f1` looks correct. You expect a function for which you say the parameter is of an unknown type, so parsing it as number is not valid - you could call the provided function with any value not just a number. But that TypeScript accepts `f3` is really weird (a bug?). Alternatively, you can use generics to automatically infer the type (which of course can lead to other problems if the main function already uses generics). If you would ever call the passed function (I guess you don't in your use case?) you would have to ensure that the value is of type `T`. ``` declare function f4<T>(fn: (x: T) => void): void; ```
`f3` is called bivariant hack. Actually, `f4` works for my case! I'll open a PR in the Jotai repo.
Ah, never heard of that. But good to know, thanks.
This might help solve a current problem of mine; do you have any idea if I could use a generic when my function must accomodate any number of arguments? What I have currently: ```js export const usePreparedAsync = <TResult, TError>( asyncFunc: (...args: unknown[]) => Promise<TResult> ): ReturnPrepared<TResult, TError> => { // ...some state setup... const run = async (...args: unknown[]) => { // ... await asyncFunc(...args).then(...) // ... return { aborted: unmountController.signal.aborted, result: resolvedValue, } as ResultPrepared<TResult> } return { run, isRunning, result, error } } ``` When I try to replace `unknown[]` with a generic type... ``` const usePreparedAsync = <TResult, TError, TArgs = unknown[]>( asyncFunc: (...args: TArgs) => Promise<TResult>, ) ``` ...I get a warning: A rest parameter must be of an array type.ts(2370) (parameter) args: TArgs
It should work if you define that `TArgs` must be an array: ``` usePreparedAsync = <TResult, TError, TArgs extends unknown[] = unknown[]> ```