hyundeock
hyundeock

Reputation: 515

A simple way to set argument types for each function type in typescript

How to set argument type for each function type in typescript?

each function is parameter.

[Example]

type F1 = (arg: number) => void;
type F2 = (arg: string) => void;

const caller = (f: F1 | F2) => (n: number | string): void => f(n); 


<error>
parameter n: string | number
Argument of type 'string | number' is not assignable to parameter of type 'never'.
Type 'string' is not assignable to type 'never'.

typescript code is removed when comiled.

so, I think any logical code is not working...

how to do this?

[try]

(f as F1)(n as number);
(f as F2)(n as string);

But, it is not cool..

Thank you.

Upvotes: 1

Views: 338

Answers (2)

zixiCat
zixiCat

Reputation: 1059

@Denis Frezzato 's answer works perfectly, but if you want to deal with more complicated situations in which the function will return respective type. Then you can think about this solution.

interface FnMap {
   F1:  (arg: number) => void;
   F2:  (arg: string) => void;
   F3:  (arg: string[]) => boolean;
   F4:  (arg: boolean) => number;
}

const caller = <T extends FnMap[keyof FnMap]>(f: T) => f

declare const fn3: (x: string[]) => boolean
caller(fn3)(['1']) // return boolean type

declare const fn4: (x: boolean) => number
caller(fn4)(true) // return number type

Upvotes: 1

Denis Frezzato
Denis Frezzato

Reputation: 968

The argument must be a type variable.

type F<A> = (a: A) => void

const caller = <A>(f: F<A>) => (a: A): void => f(a)

declare const fn: (x: number) => void

caller(fn)(1) // Ok
caller(fn)('e') // Argument of type 'string' is not assignable to parameter of type 'number'.

If you want to restrict to number | string:

type F<A extends number | string> = (a: A) => void

const caller = <A extends number | string>(f: F<A>) => (a: A): void => f(a)

Upvotes: 1

Related Questions