Typed Routes with TypeScript

Reposted from the Esper Tech Blog.

Although Esper started out as an OCaml shop, we also use quite a bit of TypeScript to build our front-end. “Why We Use TypeScript” would probably be a long post in and of itself, but this post is about how we use TypeScript to implement a small, open-source library that implements statically-typed route checking.

If you don’t care about the why or how, you can check out said library on Github or download the typed-routes package on NPM.

Routing

By routing, we mean taking some action based on a file-like string path. The path in question is usually a URL, and routing can occur on a web app backend, by the frontend for a single page app, or even by a mobile app.

Probably the most popular way of representing routes in JavaScript-land is an Express-style path (which is typically implemented using the path-to-regexp package). An Express-style path looks like this: /path/to/:arg1/:arg2. It matches /path/to/abc/123, and it captures the third and fourth parts of that path inside a param object that looks like: { arg1: "abc", arg2: "123" }.

This works well enough, but it’s not ideal from a static type-checking perspective. In TypeScript at least, /path/to/:arg1/:arg2 is just a string. There isn’t much it can (currently) do to parse out the parameters. Nor is there much it can do to verify that arg2 is an integer.

[X in keyof S]: S[X] null;
More …

react-redux-set-local

Redux’s dispatch / action / reducer architecture makes it easy to reason about complex state management. Plus the dev tools and overall community support is fantastic.

However, Redux is overkill for state that’s local to a specific component (e.g. is this dropdown open?). Redux’s state management is, by design, independent of React’s component architecture. Separating presentation logic from your state management code is great, but a standard React-Redux implementation (even using the helpful react-redux library) still requires a lot of glue code to hold everything together. Even simple state changes require all of the the following:

  • An action to represent changes to the component state
  • A reducer to apply the action to our store state
  • Code to hook the reducer to the store
  • The React component itself
  • Container code hooking up the React component to code that dispatches our actions

The simplest alternative to this is to just use React’s setState function. But this deprives us of Redux’s dev tools and other benefits.

To address this, I spent part of this weekend writing react-redux-set-local. The name’s a mouthful, so let’s call it RRSL.

More …

Property removals in TypeScript

A quick note about how to easily go from a broader type to a narrower one in TypeScript.

Suppose you have the following two interfaces:

interface ABC {
  a: number;
  b: string;
  c: boolean;
}

interface AB {
  a: number;
  b: string;
}

We want to convert a var from ABC to AB. Although ABC meets all the constraints of AB, the additional excess properties sometimes break things and TypeScript will, sometimes, complain about them.

So we could just do this:

declare var myVar: ABC;
delete myVar.c;

But that’s not really desirable because, assuming TypeScript even lets you do that, you’re mutating an existing typed object. myVar is still typed as ABC, even though it no longer has a c property.

I used to frequently write code that cloned myVar, deleted the extra property, and then typecast the clone to a new interface. But with the introduction of destructuring and spread operator support in TypeScript 2.1, it’s actually quite simple now:

let { c, ...newVar } = myVar

Tada! newVar is created without the c property, and TypeScript recognizes it.

Free College, Academic Freedom, and Choice

Free college is apparently all the rage on the left these days. For the purposes of discussion, let’s assume we find a way to actually fund free tuition, materials, and room and board at all public colleges in America. But even if that’s the case, free college isn’t something that liberals should be quick to embrace.

For starters, what would free college do to academic freedom? If higher education is a public good, it follows that the content of higher education is a question for the democratic process. But academic freedom is about the freedom to teach and learn about topics that may not be popular. We already see skirmishes over, for instance, whether the government should fund political science or climate change research. If college was 100% publicly funded, we’d probably get more of that, similar to how state legislatures routinely try to change the content of history books and teach creationism in public schools.

More …