6

Ok, I have the following scenario:

type IHashFn = (arg: string) => number;
const hash: IHashFn = (arg) => {
  return 42;
}

So far, so good. Now I want the function to be generic.

const hash: <T> (arg: T) => number = (arg) => {
  return 42;
}

That works. But this doesn't:

type IHashFn<T> = (arg: T) => number;
const hash: <T> IHashFn<T> = (arg) => {
  return 42;
}

I found no way to calm down the TS compiler. Using interfaces instead of type aliases doesn't work either.

Note: I dont't want hash to be an implementation for IHashFn<string> but generic as well.

Is there a way to declare generic function types or interfaces in TypeScript at all?

3 Answers 3

4

You aren't really doing anything with your generic parameter.

But it sounds like you want a generic function, not a generic type alias. So leave it on the function, and off of the type alias.

type IHashFn = <T>(arg: T) => number;

const hash: IHashFn = (arg) => {
  return 42;
}
Sign up to request clarification or add additional context in comments.

Comments

2

The solution is to use the built-in Typescript utilities Parameters and ReturnType.

For your case:

type IHashFn<T> = (arg: T) => number;
const hash: <T> (...args: Parameters<IHashFn<T>>) => ReturnType<IHashFn<T>> = (arg) => {
  return 42;
}

There might be a cleaner way with the keyword infer used directly, but I could not find it. Maybe someone else can add it here.

I had the same question and it was impossible to find a solution for me, I had to learn about the existence of these utilities and figure it out by myself.

In my case, I wanted to take advantage of the existing React.FunctionComponent (or React.FC) type alias, while using a generic.

List of utility types: https://www.typescriptlang.org/docs/handbook/utility-types.html

More info on infer: https://blog.logrocket.com/understanding-infer-typescript/

3 Comments

Oof, one year ago. I remember that I was playing with React.FC for a generic createRoute function.
Thanks. That’s a clever, albeit verbose, solution. I did have to substitute ReturnType for ResultType, though. Maybe that was renamed at some point?
It was ReturnType, not ResultType, I don't know how I made this mistake
0

You can simply use IHashFn<any>. This will be usable where IHashFn<string> is expected too.

If you truly want it to still be a generic function type, you could do something like this:

type IHashFn<T = any> = <U extends T>(arg: U) => number;

Comments

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.