Leveraging TypeScript's ReturnType for Handling Unexported Types

Leveraging TypeScript's ReturnType for Handling Unexported Types
Photo by Lili Popper / Unsplash

Ever work with a library that exports a function but not a type for the value it returns? Or need to work with generated clients that do not explicitly declare a type? It's a problem and you encounter it as soon as you want to pass one of these types to another function.

any might seem tempting, but I'm here to tell you not to. ReturnType to the rescue.

Here's an example:

function createComplexType() {
  return { value: 42 };

Well, not really complex but you get the idea. Just imagine it's more complex. Either way, this function does not explicitly declare its return type so what can we do.

We can declare our own using ReturnType

type UnexportedType = ReturnType<typeof createComplexType>;

const data: UnexportedType = { value: 42 };

Working with really complex types like the ones generated by graphql-zeus? Let's use ReturnType to create a type for Chain so we can pass this client around:

import { Chain } from "zeus";

export type GraphQLClient = ReturnType<typeof Chain>;

Enjoy your types and consider PR'ing your favorite libraries to add types in situations like these, since the best types are the ones you don't have to maintain or declare yourself.