Elm Architecture in 8 lines of TypeScript

Yiyi Sun
3 min readMar 8, 2018

--

Elm is awesome! Like many other people, I like Elm. The main reason for me to like it is its architecture, the famous Elm Architecture. However, Elm’s Haskell style syntax is a deep learning curve to me. On the other hand, I like TypeScript too. It turns out that I can define the Elm Architecture in 8 lines of TypeScript.

In the Elm architecture, the application logic breaks up into three parts.

  • Model: the state of your application
  • View: a function to display the application state
  • Update: a set of functions to update the application state

Model and state are the two terminologies referring to the same thing, which is the application state at any given time. It can be any type, e.g., a number, an array and an object, whatever best represents the application state. We can abstract the type of state as T and use the TypeScript generic type to define the View and Update.

The View is a function to display the application state of any type.

type View<T> = (state: T) => string;

The Update is a set of functions to update the application state. It is a dictionary of actions. Each action creates a new state out of current state.

type Action<T> = (state: T) => T;
type Update<T> = {[name: string]: Action<T>};

Finally, the start function that has strong typed state, view and update.

interface IApp {
start<T>(
element: HTMLElement | string,
model: T, view: View<T>, update: Update<T>): void;
}

All in 8 lines, it forms the generic based Elm architecture.

To use the architecture, we can leverage the TypeScript feature that is to use the typeof operator for defining the type alias out of an existing object. Then we can use the type alias to build an application class, where its state, view, and update are strongly typed to the type alias.

const state = { msg: 'Hello' };
type State = typeof state;
const view: View<State> = state => <h1>{state.msg}</h1>;
const update = {
'#': async (state: State) => state
}
app.start('my-app', state, view, update);

I have created the AppRun library to help build applications of the Elm architecture. AppRun is flexible. It does not force you must have a build environment. You can use it in a script tag and code in plain JavaScript without any build process, which is very good for small size applications. AppRun also supports and recommends using TypeScript, especially for larger applications.

The type definition in the AppRun library is a little more complicated because AppRun uses event pub-sub, virtual DOM, async/await, and has statelful component and stateless component. It is still in 8 lines.

Elm Architecture in AppRun

When using AppRun in Visual Studio Code, it gives us all sort of good things, such as type checking, auto-completion, find references, code navigation, refactoring, and code lens.

Typed AppRun Component

Hope you enjoy . You can visit the AppRun library on Github for more good stuffs. https://github.com/yysun/apprun

--

--