Jess
Jess

Reputation: 90

Getting type of function inside closure

I've done some searching around and can't find an answer that seems to solve this particular problem I have. Any help would be great.

I'm currently using closures for basic dependency injection and I'm trying to avoid functions getting given "any";

Lets say I have the following:

// db-fns.ts

export const makeQuerySql = ({pool: SqlPool}) => 
    <T>(query: string, args?: any): Promise<T> => {
       // fn code
    }

// user-fns.ts

export const makeGetUser = ({querySql}: Dependencies) => (userId: number) => {
   // fn code
}
export interface Dependencies {
  querySql: ????
}

// index.ts

import {makeQuerySql} from 'db-fns.ts';
import {makeGetUser} from 'user-fns.ts';
const querySql = makeQuerySql({pool});
const getUser = makeGetUser({querySql});

I can't see how I would get the typeof querySql in the dependencies interface in user-fns.ts

Upvotes: 0

Views: 56

Answers (1)

jcalz
jcalz

Reputation: 327984

Well, you've declared that makeQuerySql returns a <T>(query: string, args?: any) => Promise<T>, so if you definie it like this:

export interface Dependencies {
  querySql: <T>(query: string, args?: any) => Promise<T>
}

Then your code in index.ts type checks.

As far as I can tell, that is the answer to your question as stated.


I'm skeptical though. Does makeQuerySql really produce a <T>(query: string, args?: any) => Promise<T>? That would be a function that returns a Promise<T> for any type value of T, despite the fact that neither of the function's parameters have anything to do with the type T. How does it do that?

You also need to specify a type for the SqlPool variable in your makeQuerySql call, or it will be any implicitly. Something like

({ pool: SqlPool }: { pool: TypeOfSqlPool }) =>
  <T>(query: string, args?: any): Promise<T>

where TypeOfSqlPool is replaced with the type you want the SqlPool variable to be.

Hope that's of some help; good luck!

Upvotes: 1

Related Questions