typescripttypescript-genericstype-systems

function types with generics and function expressions


Say I have the definition of a generic function that does something to a value of type T:

function doSomething<T> (t: T): void {
    // do something on a value of type T
    console.log(t);
}

Now, I want to capture the type of that function. E.g. a use case might be that I want to use it in further, more complicated types I may plan to define down the road. It's function type could be defined as:

type DoSomething<T> = (t: T)=>void

So far so good. However nothing in my code, so far, says that doSomething is of type DoSomething.

Now the problem arises when I want to declare that function doSomething indeed is of type DoSomething.

If I try to do it in the following way by assigning the value of a function expression to a variable (I know of no other syntax to accomplish this):

const doSomething: DoSomething<T> = (t: T): void=>{
  // do something on a value of type T
  console.log(t)
}

… then the TypeScript type system complains Cannot find name 'T'.

In fact (I think) I do understand why the type system complains as it has no way of inferring what T is. What I don't understand is why I didn't have the same problem when doSomething was defined equivalently as a function (as opposed to a function expression assigned to a const).

Also, how one should properly go about declaring that a function has a given type?

TypeScript Playground here.


Solution

  • The problem here is that the generic type T is in the wrong position. You don't want the type DoSomething to be generic. You want the function to be generic.

    type DoSomething = <T>(t: T) => void
    
    const doSomething: DoSomething = (t): void => {
      console.log(t)
    }
    

    Playground