Some useful functions and types.
Set of functions and types used across the different projects of Productive Codebases.
Typescript is not mandatory but highly recommended.
npm install @productive-codebases/toolbox
Ensures that all cases of a switch
are implemented by returning a never
type in the default case.
Usage:
switch (unionOfValues) {
case 'value1': {
// ...
}
case 'value2': {
// ...
}
default: {
assertUnreachableCase(unionOfValues)
}
}
Instanciate entities from a litteral objects.
Usage:
const user = createEntity(EntityUser, {
id: '1',
username: 'John'
})
const users = createEntities(EntityUser, [
{
id: '1',
username: 'John'
},
{
id: '2',
username: 'T1000'
}
])
Typed listing of keys, values and entries from an object.
Usage:
const user = {
id: '1',
username: 'John'
}
StrictObject.keys(user) // ['id', 'username']
StrictObject.values(user) // ['1', 'John']
StrictObject.entries(user) // [['id', '1'], ['username', 'John']]
Deeply merges multiple objects.
Usage:
const mergedObjects = deepMerge([object1, object2], optionalOptions)
Ensures that a value is an array.
Usage:
ensureArray(x).map(...)
Ensures that a value is a set.
Usage:
ensureSet(x).forEach(...)
Add or remove a Set
value to a map.
Usage:
const map = new Map<string, Set<number>>()
addSetValueToMap(map, 'scores', 42)
addSetValueToMap(map, 'scores', 92)
const numbers = map.get('scores')
numbers.size // 2
Index / Append entities (objects) to a map.
Usage:
const users = [
{
id: 1,
name: 'Bob'
},
{
id: 2,
name: 'Alice'
},
{
id: 3,
name: 'John'
}
]
const usersMap = indexEntitiesToMap(users, 'id')
const bobUser = usersMap.get(1)
const users = [
{
id: 1,
name: 'Bob',
lastName: 'Foo'
},
{
id: 2,
name: 'Alice',
lastName: 'Foo'
},
{
id: 3,
name: 'John',
lastName: 'Bar'
}
]
const usersMap = appendEntitiesToMap(users, 'lastName')
const usersHavingFoo = usersMap.get('Foo')
usersHavingFoo.size // 2
Returns a type predicate to remove undefined or nullable values of an array.
Usage:
if (isDefined(x)) {
//...
}
const values = [null, undefined, '', 'value', 0].filter(isDefined)
values.length // 3
Returns a type predicate to filter falsy values of an array.
Usage:
if (isNotFalsy(x)) {
//...
}
const values = [null, undefined, '', 'value', 0].filter(filterFalsies)
values.length // 1
Return true if the value is truthy.
Usage:
if (isTruthy(x)) {
//...
}
Return a composite function allowing to log message from a defined logger mapping.
const loggerMapping = {
server: {
express: 'express',
middleware: 'middleware'
},
client: {
react: 'react',
store: 'store'
}
}
const { newLogger } = setupLogger(loggerMapping)
const logger = newLogger('server')('middleware')
logger('info')('Send request')
logger('error')('Error 500')
You can enable / disable logger messages by adding a debug
property in local storage. Example:
// Will show only log messages for the server middleware:
localStorage.set('debug', 'server:middleware:*')
Metadata-like data storage.
Usage:
interface IMetaData {
data: string
}
const metadata = new MetaData<IMetaData>()
metadata.set({ data: 'foo' })
const value = metadata.get('data')
Define a value that can be null.
Usage:
type Value = Maybe<string>
Define a value that can be undefined.
Usage:
type Value = MaybeUndef<string>
Define a value that can be null or undefined.
Usage:
type Value = Perhaps<string>
Define an object with all properties as nullable values.
Usage:
interface IUser = {
id: number
name: string
}
const user: PropertiesNullable<IUser> = {
id: null,
name: null
}
Define an object with all properties as non-nullable values.
Usage:
interface INullableUser = {
id: Maybe<number>
name: Maybe<string>
}
const user: PropertiesNonNullable<INullableUser> = {
id: 1,
name: null // Error
}
Partial applyed deeply.
Usage:
interface IUser = {
id: number
name: string
address: {
city: string
country: string
}
}
const user: PartialDeep<IUser> = {
id: 1,
address: {
country: 'France'
}
}