Clean TypeScript code with type guards
Do you search for a cleaner code in TypeScript? You can start by using TypeGuards!
Read this storyAbout 4 minutes length
This is a small one.
When you have a type T
(which maybe represents an object), you will of course need a way to build, hydrate and validate an instance of T
.
You could do everything by hand, but it's not really a good idea: the type could change or you could risk to bloat your code or whatever.
Here's the simplest but deadly efficient way of creating a factory which creates and hydrates and object's instance.
export interface MyObject {readonly myprop1: string;readonly myprop2: number[];readonly myprop3: { [index: string]: number[] };readonly myprop4: Date;}//#region factoriesexport const create = (partial: Partial<MyObject> = {}): MyObject => ({myprop1: partial.myprop1 ?? ``,myprop2: [... partial.myprop2],myprop3: { ... partial.myprop3 },myprop4: partial.myprop4 ?? new Date(),})//#endregion
This way, you will be able to both create and hydrate your type T
.
The biggest issue comes with validation.
To add it, I'll create a typeguard using a library called tiinvo
import { anyof, check, isfunction, isstring, implementing, isarrayof, isnumber, isindexable, haskeyoftype } from 'tiinvo'export interface MyObject {readonly myprop1: string;readonly myprop2: number[];readonly myprop3: { [index: string]: number[] };readonly myprop4: Date;}//#region typeguardsexport const isMyObject = implementing<MyObject>({myprop1: isstring,myprop2: isarrayof(isstring),myprop3: isindexable,myprop4: anyof(haskeyoftype('getDate', isfunction),haskeyoftype('getFullYear', isfunction),haskeyoftype('getMonth', isfunction),),});//#endregion//#region factoriesexport const create = (partial: Partial<MyObject> = {}): MyObject => ({myprop1: partial.myprop1 ? check(isstring(partial.myprop1), 'myprop1 is not a string')(partial.myprop1) ``,myprop2: partial.myprop2 ? isarrayof(isnumber)(partial.myprop2) [... partial.myprop2],myprop3: { ... partial.myprop3 },myprop4: partial.myprop4 ?? new Date(),})//#endregion
Doing this way, we could import the module and with enough safety we could create and/or validate a type T
import * as TMyObject from 'types/MyObject';const t1 = TMyObject.create()const t2 = TMyObject.create({ myprop1: 'name' })TMyObject.isMyObject(t1) // trueTMyObject.isMyObject(t2) // trueTMyObject.isMyObject({}) // false
Do you search for a cleaner code in TypeScript? You can start by using TypeGuards!
Read this storyNodejs modules are singletons
Read this storyBored of checking incoming JSON data from clients? Try with a middleware and typeguards!
Read this storyAs a functional programming library, tiinvo can help a lot for clean code
Read this story