typescript: typing functions

2021-09-13

 | 

~2 min read

 | 

303 words

In Javascript, we can write functions as declarations or expressions.

And while I typically write my functions as expressions, I normally rely on the compiler to tell me what my return type is.

In his Frontend Master’s workshop, Production-Grade Typescript, Mike North encourages strongly typing your functions to avoid accidentally changing the contract of a function. So, I’ve been trying to do that more lately!

Let’s do a quick refresher on how we might type functions as declarations and expressions then.

For our example, we’ll use a combiner function that will take the elements from two objects and combine them into one. The Javascript might look like this:

function combine(objA, objB) {
  return { ...objA, ...objB }
}

But what if we want to only be able to combine specific objects?

types.ts
type Vendor = { vendorId: number }
type Item = { itemId: number }
type VendorItem = Vendor & Item

How would we write a combine that returns a VendorItem?

With a function declaration, the type comes after the arguments and before the opening brace of the function:

combineDeclaration.ts
function combine(item: Item, vendor: Vendor): VendorItem {
  return { ...item, ...vendor }
}

What about function expressions though? In this case, the variable receiving the assignment is being assigned to a function, not the return value of the function. Bearing this in mind, we’ll see that the typing actually combines all of the aspects of the function declaration in one concise statement:

combineExpression.ts
type AugmentFn = (item: Item, vendor: Vendor) => VendorItem

const augmentItem: AugmentFn = (item, vendor) => {
  return { ...item, ...vendor }
}

Once we remember what the functional expression is actually doing (assigning a function to a variable), the fact that we’re not typing just the return type makes a lot of sense!



Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!