Problem
I have created a Typescript package that shares types between my backend node firebase cloud functions and my fronted React client that calls them. Below are some samples of the types.
interface FirstFunctionInput {
x: number
}
interface SecondFunctionInput {
y: string
}
// defines all available functions
enum FirebaseFunction {
FirstFunction = "firstFunction",
SecondFunction = "secondFunction"
}
This is how I am calling the functions currently, using the firebase sdk:
firebase.funtions.httpsCallable('firstFunction')({ x: 21 })
.then(result => { ... })
My problem here is
- There is no guarantee that the function 'firstFunction' exists
- Even if it does, how can I be sure that it accepts a parameter such as
{ x: 21 }.
So what I am trying to achieve is a way to write a utility method using Generics that overcomes these problems.
Ideal solution
Below is an example of how I'd (ideally) like the API to look. I have provided an example where the wrong input type is provided to the function, and I expect Typescript to show an error.
callFirebaseFunction<FirstFunction>({ y: 'foo' })
^----------^
show error here, since FirstFunction must take a FirstFunctionInput
Current (but not quite there yet) solution
I have come close to achieving this, with an API that works, however it requires the input params to be specified at the calling location:
callFirebaseFunction<FirstFunctionInput>(
FirebaseFunction.FirstFunction,
{ x: 21 }
)
.then(result => { ... })
This is not ideal because the input type needs to be known by the programmer, in order to specify it.
Final Words
I have tried all different combinations of interfaces that are extended, abstract classes that are extended and even the builder pattern, but I cannot find a way to tie this all together. Is something like this even possible?