Skip to content

Latest commit

 

History

History
65 lines (49 loc) · 1.96 KB

io-ts.md

File metadata and controls

65 lines (49 loc) · 1.96 KB

back

Data Decoding with io-ts

Introduction

Since the backend of this application is developed and operated by a third party, we use io-ts to ensure the received data from the API conforms to the expectations. The mechanism works as follows:

  • We define runtime (io-ts) types.
  • We derive the compile-time TypeScript types from these runtime types.
  • We decode the received data over the API using the defined runtime types. If the data does not comply to the definition, a DecodeError exception is thrown. The discrepancy can therefore be discovered at the earliest possible stage, with a very clear description of the problem. Any subsequent errors and undefined behavior of the application can be prevented.
  • We use custom types (like LocalDateTimeFromString and LocalDateFromString) to transform data.

Best Practices

Type Definition

Runtime types are described in a .model.ts file in the src/app/shared/models directory:

import * as t from 'io-ts';

const Person = t.type({
  Id: t.number,
  FirstName: t.string,
  LastName: t.string
});

type Person = t.TypeOf<typeof Person>;
export { Person };

The runtime and TypeScript types are exported under the same name and can be used in their appropriate contexts without having to think about which one to use.

Avoid Checking Unused Properties

Any additional properties that are received but are not used within the application (e.g. a MatriculationNumber on Person), should be omitted from the type definition. These properties then stay in the decoded object, but are ignored when type checking. The goal is to not generate unnecessary exceptions.

Decoding

The decode and decodeArray utility functions can be used to type-check and decode the received data:

function getPerson(id: number): Observable<Person> {
  return this.http
    .get<unknown>(`/api/Persons/${id}`)
    .pipe(switchMap(decode(Person)))
    .subscribe(...);
}