0

This is working, no problem:

type fun = (uid: string) => string 

const abc: fun = value => value

const efg = (callback:fun, value:string) =>callback(value)

console.log(efg(abc, "123"))

But if we go for generic, it will error:

type fun = (uid: string) => string 

const abc: fun = value => value

const efg = <T>(callback:T, value:string) =>callback(value)

console.log(efg(abc, "123"))

Error:

This expression is not callable. Type 'unknown' has no call signatures.(2349)

TypeScript Playground demo

I read https://www.typescriptlang.org/docs/handbook/generics.html but it say nothing about Generic Function Type Literals.

I need to pass different functions as an argument, which is why I need this.

Is there any work around/hack or there is actually a proper way to do this?

2 Answers 2

2

The problem is that T type is not constrained, so it can be anything, you can pass there number, string etc. Its clear that you cannot call number like it would be function.

How you treat T in your code is as it would be function with string argument, therefor such constraint need to be given. Consider:

const efg = <T extends (a: string) => any>(callback: T, value: string) => callback(value)

Above T is constrained (by extend keyword) as a function which takes string and can return anything. It means that all functions like string->number, string-> boolean, string->object etc are ok.

We can go further and constraint it more (if you need) and say our function is only string->string, and exactly such interface is given by fun type. So lets extend fun:

const efg = <T extends fun>(callback: T, value: string) => callback(value)

Playground

Sign up to request clarification or add additional context in comments.

Comments

0

The following, based on rxjs's UnaryFunction might work for you.

TypeScript Playground demo:

interface Callable<T> {
    (source: T): T;
}

interface CallableInvoker<T> {
    // If the return type also needs to be T, replace any with T
    (callback: Callable<T>, value: T): any
}


function doubleNumber(value: number): number {
    return value * 2;
}

function doubleString(value: string): string {
    return value + value;
}

const efg: Callable<number> = doubleNumber; // Valid
const efg2: Callable<number> = doubleString; // Invalid, doubleString  must match the generic type

const efg3: CallableInvoker<number> = (doubleNumber, value) => doubleNumber(5);

9 Comments

I know Function exist, but I cant manipulate it like I manipulate Generic, for example if I want to utilize the return type of that function or the type of that function argument or return the same function type to my HOC, can Function type help with this?
The following line isn't valid TS, but hypothetically, are you looking for something resembling this: const efg = <T>(callback: Function<T>, value:string) =>callback(value) where T is the return type of the callback?
Ya, you can think something like that, or something like this const efg = <T>(callback:(argumentsTypeOfT)=>returnTypeOfT, value:string) =>callback(value) that allow me to do something with T
I think I've got something for you. I'll update my answer shortly.
const efg: Callable<number> = {doubleNumber()} this will error if I try to call it
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.