Generic Type Inference through Function Arguments in TypeScript
Occasionally you’ll find yourself in a situation where untyped data enters your system through a uniform entry point, and you’re left with the challenge of mapping it into types within your application.
Consider a webhook driven system where a client calls a single endpoint with multiple types of data, where the type of data is indicated by a property of the payload.
For example:
POST: /message
BODY: {
type: "TextMessage",
userId: 123,
message: "Hello World"
}
and
POST: /message
BODY: {
type: "ImageMessageWithText",
userId: 123,
message: "A picture of my cat"
imageUrl: "http://catpicture.png"
}
If we ignore the fact that /message
should likely be split up into multiple endpoints /message/text
and /message/imageMessageWithText
or the type of data hinted through metadata such as HTTP Headers, we’re faced with an interesting decision on how we deal with the complexity these integrations can have on a typed program. It is often the case that changing how the calling system works is out of our control, but that doesn’t mean our solution to handling these requests has to be unwieldily.
This post will discuss how to deal with this situation in a maintainable and type safe way using Generic Type Inference through Function Arguments in TypeScript.