@i-doit/enten-types
v1.0.5
Published
Enten Types is a library to create type-safe guards to check the shape of unknown data
Downloads
19
Readme
Enten Types
Enten Types is a library to create type-safe guards to check the shape of unknown data
Installation
npm install @i-doit/enten-types
Guards
You can define the shape of the expected data using the type guards.
The following guards are available:
isString, isNumber, isBoolean
These guards check if an argument has a specific type.
For example,
const data = await fetch('/api/data').then(a => a.json());
if (isNumber(data)) {
// data is a number
}
isObject
isObject
checks if an argument is an object.
isObjectWithShape
checks if it's an object with predefined shape. It receives key-value pairs with guards for each field.
isMapOf
checks if it's an associative array with all values matching the passed guard.
For example,
const isApiEntry = isObjectWithShape({
id: isString,
order: isNumber,
active: isBoolean,
});
const data = await fetch('/api/data').then(a => a.json());
if (isApiEntry(data)) {
// data has type
// {
// id: string;
// order: number;
// active: bool;
// }
}
if (isMapOf(isApiEntry)(data)) {
// data has a type Record<string, ApiEntry>
}
isArray
isArray
checks if an argument is an array.
isArrayOf
checks if an argument is an array and every element of the array matches the passed guard.
For example,
const data = await fetch('/api/data').then(a => a.json());
if (isArrayOf(isApiEntry)(data)) {
// data has type ApiEntry[]
}
Optional
Optional guard allows you to create a guard that allows undefined.
For example,
const isApiEntry = isObjectWithShape({
id: isString,
title: optional(isString),
})
// isApiEntry checks if an argument has the shape:
// {
// id: string;
// title?: string;
// }
isExact
isExact checks if the value has exactly the same value as expected.
This can be useful to create the discriminator maps.
const isEqFilter = isObjectWithShape({
operation: isExact<'eq'>('eq'),
value: isString,
field: isString
});
// EqFilter has type
// {
// operation: 'eq';
// value: string;
// field: string;
// }
Extracting the type of the Guard
To retrieve the type that supports guard, you can use GetType
type:
For example,
const isApiEntry = isObjectWithShape({
id: isString,
title: isString,
name: optional(isString),
});
type ApiEntryType = GetType<typeof isApiEntry>;
// ApiEntryType is
// {
// id: string;
// title: string;
// name: string | undefined;
// }
This way you can define your type using the guards.
OrX and AndX
You can combine guards together using andX or orX:
const isIdentifiable = isObjectWithShape({
id: isString
});
const isUser = andX(isIdentifiable, isObjectWithShape({
username: string
}));
Composition
You can combine your guards to create new ones:
const isApiResponse = isObjectWithShape({
offset: isNumber,
total: isNumber,
});
const isUserApiResponse = andX(isApiResponse, isObjectWithShape({
results: isArrayOf(isUser)
}))
type UserApiResponse = GetType<typeof isUserApiResponse>;
NPM scripts
npm t
: Run test suitenpm start
: Runnpm run build
in watch modenpm run test:watch
: Run test suite in interactive watch modenpm run test:prod
: Run linting and generate coveragenpm run build
: Generate bundles and typings, create docsnpm run lint
: Lints codenpm run commit
: Commit using conventional commit style (husky will tell you to use it if you haven't :wink:)