Case Statement in Typescript

June 24, 2020 ยท 1 minute read

One of my favorite features of functional languages like Elm is pattern matching. Here is an example:

type State
	= Loading
	| Error
	| Ok

stateToString : State -> String
stateToString state =
	case state of
		Loading ->
			"Loading ..."

		Error ->
			"Something went wrong."

		Ok ->
			"It's all good"

I found a simple way to provide an action for every case of a TypeScript enum.

enum State {
	Loading,
	Error,
	Ok,
}

const STATE_MAP = {
	[State.Loading] : () => "Loading ...",
	[State.Error] : () => "Something went wrong.",
	[State.Ok] : () => "It's all good",
}

function stateToString(state : State) : string {
	return STATE_MAP[state]();
}

Link to TypeScript playground

Usually TypeScript won't allow bracket notation to access properties of an object. In this case the compiler knows that all cases of State are accounted for and can thus be used to index into the object.

Try removing one of the states from STATE_MAP and the TypeScript compiler will yell at you.

Element implicitly has an 'any' type because expression of type 'State' can't be used to index type '{ 0: () => string; 1: () => string; }'.
  Property '[State.Ok]' does not exist on type '{ 0: () => string; 1: () => string; }'.