https://github.com/ivanhofer/typesafe-utils
A collection of a few small lightweight typesafe utilities.
https://github.com/ivanhofer/typesafe-utils
typescript utils
Last synced: 10 months ago
JSON representation
A collection of a few small lightweight typesafe utilities.
- Host: GitHub
- URL: https://github.com/ivanhofer/typesafe-utils
- Owner: ivanhofer
- Created: 2020-12-21T06:43:52.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2023-03-05T18:13:38.000Z (almost 3 years ago)
- Last Synced: 2025-03-30T14:22:25.014Z (11 months ago)
- Topics: typescript, utils
- Language: TypeScript
- Homepage:
- Size: 515 KB
- Stars: 88
- Watchers: 2
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
A collection of a few small lightweight typesafe utilities.
## Motivation
Sometimes you will encounter situations were the types will **not** match what you expect from a function. This means you need to explicitly specify a type by yourself to gain the full power of TypeScript.
In this collection you will find some useful functions that are fully typed.
## Install
```
$ npm install --save-dev typesafe-utils
```
## Overview
- [filter functions](#filter functions)
- is
- [is](#is)
- [isNot](#isNot)
- [isProperty](#isProperty)
- [isPropertyNot](#isPropertyNot)
- isTruthy
- [isTruthy](#isTruthy)
- [isFalsy](#isFalsy)
- [isPropertyTruthy](#isPropertyTruthy)
- [isPropertyFalsy](#isPropertyFalsy)
- [arePropertiesTruthy](#arePropertiesTruthy)
- [arePropertiesFalsy](#arePropertiesFalsy)
- isUndefined
- [isUndefined](#isUndefined)
- [isNotUndefined](#isNotUndefined)
- [isPropertyUndefined](#isPropertyUndefined)
- [isPropertyNotUndefined](#isPropertyNotUndefined)
- [arePropertiesUndefined](#arePropertiesUndefined)
- [arePropertiesNotUndefined](#arePropertiesNotUndefined)
- isNull
- [isNull](#isNull)
- [isNotNull](#isNotNull)
- [isPropertyNull](#isPropertyNull)
- [isPropertyNotNull](#isPropertyNotNull)
- [arePropertiesNull](#arePropertiesNull)
- [arePropertiesNotNull](#arePropertiesNotNull)
- boolean
- [isBoolean](#isBoolean)
- isTrue
- [isTrue](#isTrue)
- [isNotTrue](#isNotTrue)*
- [isPropertyTrue](#isPropertyTrue)
- [isPropertyNotTrue](#isPropertyNotTrue)*
- [arePropertiesTrue](#arePropertiesTrue)
- [arePropertiesNotTrue](#arePropertiesNotTrue)*
- isFalse
- [isFalse](#isFalse)
- [isNotFalse](#isNotFalse)*
- [isPropertyFalse](#isPropertyFalse)
- [isPropertyNotFalse](#isPropertyNotFalse)*
- [arePropertiesFalse](#arePropertiesFalse)
- [arePropertiesNotFalse](#arePropertiesNotFalse)*
- number
- [isNumber](#isNumber)
- isZero
- [isZero](#isZero)
- [isNotZero](#isNotZero)*
- [isPropertyZero](#isPropertyZero)
- [isPropertyNotZero](#isPropertyNotZero)*
- [arePropertiesZero](#arePropertiesZero)
- [arePropertiesNotZero](#arePropertiesNotZero)*
- string
- [isString](#isString)
- isEmpty
- [isEmpty](#isEmpty)
- [isNotEmpty](#isNotEmpty)
- [isPropertyEmpty](#isPropertyEmpty)
- [isPropertyNotEmpty](#isPropertyNotEmpty)
- [arePropertiesEmpty](#arePropertiesEmpty)
- [arePropertiesNotEmpty](#arePropertiesNotEmpty)
- array
- [isArray](#isArray)
- [isArrayNotEmpty](#isArrayNotEmpty)
- [isArrayEmpty](#isArrayEmpty)
- object
- [isObject](#isObject)
- [isPrimitiveObject](#isPrimitiveObject)
- duplicates
- [filterDuplicates](#filterDuplicates)
- [filterDuplicatesByKey](#filterDuplicatesByKey)
- logical operators
- [and](#and)*
- [or](#or)*
- [not](#not)*
- typeguards
- [createFilter](#TypeGuardInverted)*
- [sorting functions](#sorting functions)
- number
- [sortNumberASC](#sortNumberASC)
- [sortNumberDESC](#sortNumberDESC)
- [sortNumberPropertyASC](#sortNumberPropertyASC)
- [sortNumberPropertyDESC](#sortNumberPropertyDESC)
- string
- [sortStringASC](#sortStringASC)
- [sortStringDESC](#sortStringDESC)
- [sortStringPropertyASC](#sortStringPropertyASC)
- [sortStringPropertyDESC](#sortStringPropertyDESC)
- date
- [sortDateASC](#sortDateASC)
- [sortDateDESC](#sortDateDESC)
- [sortDatePropertyASC](#sortDatePropertyASC)
- [sortDatePropertyDESC](#sortDatePropertyDESC)
- [mapping functions](#mapping functions)
- [pick](#pick)
- [other](#other)
- [deepClone](#deepClone)
- [uniqueArray](#uniqueArray)
- [types](#types)
- [Truthy](#truthy)
- [Falsy](#falsy)
- [TypeGuard](#typeguard)
- [TypeGuardWithReturnType](#typeguardwithreturntype)
- [TypeGuardInverted](#typeguardinverted)
- [TypeGuardInvertedWithReturnType](#typeguardinvertedwithreturntype)
| * not automatically 100% typesafe. It's better than nothing but to be 100% typesafe you need to pass generics yourself.
## filter functions
A bunch of utilities that return true or false. Useful for array filter functions.
> Motivation: When you filter an Array, the return type is **not** always what you expect. Typescript will tell you the result of a filter function is the exact type you pass to the filter function. But that is **not** always true. If you filter out falsy values, the return type should should **not** contain.
```TypeScript
// BASIC example --------------------------------------------------------------
const result = [true, false].filter(bool => !!bool)
// => result: boolean[] => [true]
import { isTruthy } from 'typesafe-utils'
const typesafeResult = [true, false].filter(isTruthy)
// => typesafeResult: true[] => [true]
// ADVANCED example -----------------------------------------------------------
const result = ['text', null, 'another text', undefined].filter(value => value !== '')
// => result: (string | null | undefined)[] => ['text', 'another text']
import { isNotEmpty } from 'typesafe-utils'
const typesafeResult = ['text', null, 'another text', undefined].filter(isNotEmpty)
// => typesafeResult: string[] => ['text', 'another text']
```
### is
returns `true` iff value is equals to the property you pass to the function
#### Usage
```TypeScript
import { is } from 'typesafe-utils'
const result = [1, 15, 10, 43].filter(is(10))
// result: number[] => [10]
```
### isNot
returns `true` iff value is **not** equal to the property you pass to the function
#### Usage
```TypeScript
import { isNot } from 'typesafe-utils'
const result = ['text', 'forbidden', 'blabla'].filter(isNot('forbidden'))
// result: string[] => ['text', 'blabla']
```
### isProperty
returns `true` iff the attribute of the object equals the property you pass to the function
#### Usage
```TypeScript
import { isProperty } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ id: 1 },
{ id: 3 }
]
const result = items.filter(isProperty('id', 3))
// result: Product[] => [{ id: 3 }]
```
### isPropertyNot
returns `true` iff the attribute of the object is **not** equal to the property you pass to the function
#### Usage
```TypeScript
import { isPropertyNot } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ id: 156 },
{ id: 123 }
]
const result = items.filter(isPropertyNot('id', 123))
// result: Product[] => [{ id: 156 }]
```
### isTruthy
returns `true` iff value is **not** `false | '' | 0 | null | undefined`
#### Usage
```TypeScript
import { isTruthy } from 'typesafe-utils'
const result = [true, false, undefined, null].filter(isTruthy)
// result: true[] => [true]
```
### isFalsy
returns `true` iff value is `false | '' | 0 | null | undefined`
#### Usage
```TypeScript
import { isFalsy } from 'typesafe-utils'
const result = [true, false, 'text', 123, null].filter(isFalsy)
// result: (false | null)[] => [false, null]
```
### isPropertyTruthy
returns `true` iff the attribute of the object is truthy
#### Usage
```TypeScript
import { isPropertyTruthy } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ id: 1 },
{ id: null },
{ id: undefined }
]
const result = items.filter(isPropertyTruthy('id'))
// result: Product[] => [{ id: 1 }]
```
### isPropertyFalsy
returns `true` iff the attribute of the object is falsy
#### Usage
```TypeScript
import { isPropertyFalsy } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ id: 5 },
{ id: null }
]
const result = items.filter(isPropertyFalsy('id'))
// result: Product[] => [{ id: null }]
```
### arePropertiesTruthy
returns `true` iff all attributes of the object are truthy
#### Usage
```TypeScript
import { arePropertiesTruthy } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesTruthy('id', 'name'))
```
### arePropertiesFalsy
returns `true` iff all attributes of the object are falsy
#### Usage
```TypeScript
import { arePropertiesFalsy } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesFalsy('id', 'name'))
```
### isUndefined
returns `true` iff value is `undefined`
#### Usage
```TypeScript
import { isUndefined } from 'typesafe-utils'
const result = [undefined, null, true].filter(isUndefined)
// result: undefined[] => [undefined]
```
### isNotUndefined
returns `true` iff value is **not** `undefined`
#### Usage
```TypeScript
import { isNotUndefined } from 'typesafe-utils'
const result = [null, undefined].filter(isNotUndefined)
// result: null[] => [null]
```
### isPropertyUndefined
returns `true` iff the attribute of the object is `undefined`
#### Usage
```TypeScript
import { isPropertyUndefined } from 'typesafe-utils'
type Product = {
id: number | undefined
}
const items: Product[] = [
{ id: 1 },
{ id: undefined }
]
const result = items.filter(isPropertyUndefined('id'))
// result: Product[] => [{ id: undefined }]
```
### isPropertyNotUndefined
returns `true` iff the attribute of the object is **not** `undefined`
#### Usage
```TypeScript
import { isPropertyNotUndefined } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ id: 5 },
{ id: undefined }
]
const result = items.filter(isPropertyNotUndefined('id'))
// result: Product[] => [{ id: 5 }]
```
### arePropertiesUndefined
returns `true` iff all attributes of the object are `undefined`
#### Usage
```TypeScript
import { arePropertiesUndefined } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesUndefined('id', 'name'))
```
### arePropertiesNotUndefined
returns `true` iff all attributes of the object are **not** `undefined`
#### Usage
```TypeScript
import { arePropertiesNotUndefined } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesNotUndefined('id', 'name'))
```
### isNull
returns `true` iff value is `null`
#### Usage
```TypeScript
import { isNull } from 'typesafe-utils'
const result = [null, undefined].filter(isNull)
// result: null[] => [null]
```
### isNotNull
returns `true` iff value is **not** `null`
#### Usage
```TypeScript
import { isNotNull } from 'typesafe-utils'
const result = [false, null].filter(isNotNull)
// result: boolean[] => [false]
```
### isPropertyNull
returns `true` iff the attribute of the object is `null`
#### Usage
```TypeScript
import { isPropertyNull } from 'typesafe-utils'
type Product = {
id: number | null
}
const items: Product[] = [
{ id: 0 },
{ id: null }
]
const result = items.filter(isPropertyNull('id'))
// result: Product[] => [{ id: null }]
```
### isPropertyNotNull
returns `true` iff the attribute of the object is **not** `null`
#### Usage
```TypeScript
import { isPropertyNotNull } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ id: 5 },
{ id: null }
]
const result = items.filter(isPropertyNotNull('id'))
// result: Product[] => [{ id: 5 }]
```
### arePropertiesNull
returns `true` iff all attributes of the object are `null`
#### Usage
```TypeScript
import { arePropertiesNull } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesNull('id', 'name'))
```
### arePropertiesNotNull
returns `true` iff all attributes of the object are **not** `null`
#### Usage
```TypeScript
import { arePropertiesNotNull } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesNotNull('id', 'name'))
```
### isBoolean
returns `true` iff value is of type `boolean`
#### Usage
```TypeScript
import { isBoolean } from 'typesafe-utils'
const result = [true, 'some text', 1, false].filter(isBoolean)
// result: boolean[] => [true, false]
```
### isTrue
returns `true` iff value is `true`
#### Usage
```TypeScript
import { isTrue } from 'typesafe-utils'
const result = [true, 'some text', 1].filter(isTrue)
// result: true[] => [true]
```
### isNotTrue
returns `true` iff value is **not** `true`
> Note: it is currently **not** possible to make this function fully typesafe.\
> `[true, 123].filter(isNotTrue)` will have the type `(false | number)[]`
#### Usage
```TypeScript
import { isNotTrue } from 'typesafe-utils'
const result = [true, false].filter(isNotTrue)
// result: false[] => [false]
```
### isPropertyTrue
returns `true` iff the attribute of the object is `true`
#### Usage
```TypeScript
import { isPropertyTrue } from 'typesafe-utils'
type Product = {
available: boolean | null
}
const items: Product[] = [
{ available: true },
{ available: null }
]
const result = items.filter(isPropertyTrue('available'))
// result: Product[] => [{ available: true }]
```
### isPropertyNotTrue
returns `true` iff the attribute of the object is **not** `true`
#### Usage
```TypeScript
import { isPropertyNotTrue } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ available: true },
{ available: false }
]
const result = items.filter(isPropertyNotTrue('available'))
// result: Product[] => [{ available: false }]
```
### arePropertiesTrue
returns `true` iff all attributes of the object are `true`
#### Usage
```TypeScript
import { arePropertiesTrue } from 'typesafe-utils'
type Product = {
count: number
available: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesTrue('count', 'available'))
```
### arePropertiesNotTrue
returns `true` iff all attributes of the object are **not** `true`
#### Usage
```TypeScript
import { arePropertiesNotTrue } from 'typesafe-utils'
type Product = {
count: number
available: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesNotTrue('count', 'available'))
```
### isFalse
returns `true` iff value is `false`
#### Usage
```TypeScript
import { isFalse } from 'typesafe-utils'
const result = [0, false, undefined].filter(isFalse)
// result: false[] => [false]
```
### isNotFalse
returns `true` iff value is **not** `false`
> Note: it is currently **not** possible to make this function fully typesafe.\
> `[false, 123].filter(isNotFalse)` will have the type `(true | number)[]`
#### Usage
```TypeScript
import { isNotFalse } from 'typesafe-utils'
const result = [false, null].filter(isNotFalse)
// result: null[] => [null]
```
### isPropertyFalse
returns `true` iff the attribute of the object is `false`
#### Usage
```TypeScript
import { isPropertyFalse } from 'typesafe-utils'
type Product = {
available: boolean | null
}
const items: Product[] = [
{ available: false },
{ available: true },
{ available: null }
]
const result = items.filter(isPropertyFalse('available'))
// result: Product[] => [{ available: false }]
```
### isPropertyNotFalse
returns `true` iff the attribute of the object is **not** `false`
#### Usage
```TypeScript
import { isPropertyNotFalse } from 'typesafe-utils'
type Product = {
id: number
}
const items: Product[] = [
{ available: true },
{ available: false }
]
const result = items.filter(isPropertyNotFalse('available'))
// result: Product[] => [{ available: true }]
```
### arePropertiesFalse
returns `true` iff all attributes of the object are `false`
#### Usage
```TypeScript
import { arePropertiesFalse } from 'typesafe-utils'
type Product = {
count: number
available: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesFalse('count', 'available'))
```
### arePropertiesNotFalse
returns `true` iff all attributes of the object are **not** `false`
#### Usage
```TypeScript
import { arePropertiesNotFalse } from 'typesafe-utils'
type Product = {
count: number
available: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesNotFalse('count', 'available'))
```
### isNumber
returns `true` iff value is of type `number`
#### Usage
```TypeScript
import { isNumber } from 'typesafe-utils'
const result = [0, false, undefined, 5].filter(isNumber)
// result: number[] => [0, 5]
```
### isZero
returns `true` iff value is `0`
#### Usage
```TypeScript
import { isZero } from 'typesafe-utils'
const result = [0, false, undefined, 5].filter(isZero)
// result: 0[] => [0]
```
### isNotZero
returns `true` iff value is **not** `0`
> Note: it is currently **not** possible to make this function fully typesafe.\
> `[0, null].filter(isNotTrue)` will have the type `(number | null)[]`
#### Usage
```TypeScript
import { isNotZero } from 'typesafe-utils'
const result = [0, 123].filter(isNotZero)
// result: number[] => [123]
```
### isPropertyZero
returns `true` iff the attribute of the object is `0`
#### Usage
```TypeScript
import { isPropertyZero } from 'typesafe-utils'
type Product = {
price: number
}
const items: Product[] = [
{ price: 0 },
{ price: 4 },
{ price: 15 }
]
const result = items.filter(isPropertyZero('price'))
// result: Product[] => [{ price: 0 }]
```
### isPropertyNotZero
returns `true` iff the attribute of the object is **not** `0`
#### Usage
```TypeScript
import { isPropertyNotZero } from 'typesafe-utils'
type Product = {
price: number
}
const items: Product[] = [
{ price: 0 },
{ price: 12 }
]
const result = items.filter(isPropertyNotZero('price'))
// result: Product[] => [{ price: 23 }]
```
### arePropertiesZero
returns `true` iff all attributes of the object are `0`
#### Usage
```TypeScript
import { arePropertiesZero } from 'typesafe-utils'
type Product = {
count: number
speed: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesZero('count', 'speed'))
```
### arePropertiesNotZero
returns `true` iff all attributes of the object are **not** `0`
#### Usage
```TypeScript
import { arePropertiesNotZero } from 'typesafe-utils'
type Product = {
count: number
speed: string
}
const items: Product[] = [ ... ]
const result = items.filter(arePropertiesNotZero('count', 'speed'))
```
### isString
returns `true` iff value is of type `string`
#### Usage
```TypeScript
import { isString } from 'typesafe-utils'
const result = ['', false, null, 'text'].filter(isString)
// result: string[] => ['', 'text]
```
### isEmpty
returns `true` iff value is `''`
#### Usage
```TypeScript
import { isEmpty } from 'typesafe-utils'
const result = ['', false, null, 'text'].filter(isEmpty)
// result: ''[] => ['']
```
### isNotEmpty
returns `true` iff value is **not** `''`
#### Usage
```TypeScript
import { isNotEmpty } from 'typesafe-utils'
const result = ['', 5].filter(isNotEmpty)
// result: number[] => [5]
```
### isPropertyEmpty
returns `true` iff the attribute of the object is `''`
#### Usage
```TypeScript
import { isPropertyEmpty } from 'typesafe-utils'
type Product = {
label: string
}
const items: Product[] = [
{ label: '' },
{ label: 'label-1' }
]
const result = items.filter(isPropertyEmpty('label'))
// result: Product[] => [{ label: '' }]
```
### isPropertyNotEmpty
returns `true` iff the attribute of the object is **not** `''`
#### Usage
```TypeScript
import { isPropertyNotEmpty } from 'typesafe-utils'
type Product = {
label: string
}
const items: Product[] = [
{ label: 'label-123' },
{ label: '' }
]
const result = items.filter(isPropertyNotEmpty('label'))
// result: Product[] => [{ label: 'label-123' }]
```
### arePropertiesEmpty
returns `true` iff all attributes of the object are `''`
#### Usage
```TypeScript
import { arePropertiesEmpty } from 'typesafe-utils'
type Person = {
name: number
firstName: string
}
const items: Person[] = [ ... ]
const result = items.filter(arePropertiesEmpty('name', 'firstName'))
```
### arePropertiesNotEmpty
returns `true` iff all attributes of the object are **not** `''`
#### Usage
```TypeScript
import { arePropertiesNotEmpty } from 'typesafe-utils'
type Person = {
name: number
firstName: string
}
const items: Person[] = [ ... ]
const result = items.filter(arePropertiesNotEmpty('name', 'firstName'))
```
### isArray
returns `true` iff value is of type `Array`
#### Usage
```TypeScript
import { isArray } from 'typesafe-utils'
const result = [[], null, 123, [0, 1]].filter(isArray)
// result: number[][] => [[], [0, 1]]
```
### isArrayNotEmpty
returns `true` iff an array contains at least one item
#### Usage
```TypeScript
import { isArrayNotEmpty } from 'typesafe-utils'
const nonEmptyArray = ['hi']
if (!!nonEmptyArray.length) {
nonEmptyArray[0].toUpperCase() // ERROR: Object is possibly 'undefined'
}
if (isArrayNotEmpty(nonEmptyArray)) {
// TypeScript will know that the array contains at least 1 item, so it will not complain
nonEmptyArray[0].toUpperCase()
}
```
### isArrayEmpty
returns `true` iff an array contains no items
#### Usage
```TypeScript
import { isArrayEmpty } from 'typesafe-utils'
const emptyArray: string[] = []
if (isArrayEmpty(emptyArray)) {
// emptyArray does not contain any items
}
```
### isObject
returns `true` iff value is of type `object`
#### Usage
```TypeScript
import { isObject } from 'typesafe-utils'
type SomeType = {
prop?: number
}
const now = new Date()
const result = [{}, now, null, { prop: 123 }].filter(isObject)
// result: (SomeType | Date)[] => [{}, now, { prop: 123 }]
```
### isPrimitiveObject
returns `true` iff value is of the primitive type `object` and not derived from a `class` like `Date` or else.
#### Usage
```TypeScript
import { isPrimitiveObject } from 'typesafe-utils'
type SomeType = {
prop?: number
}
const now = new Date()
const result = [{}, now, null, { prop: 123 }].filter(isPrimitiveObject)
// result: SomeType[] => [{}, { prop: 123 }]
```
### filterDuplicates
Removes duplicates from an array. Only the first occurrence of an item will be kept.
#### Usage
```TypeScript
import { filterDuplicates } from 'typesafe-utils'
const items = [1, 2, 3, 5, 8, 1]
const filteredItems = items.filter(filterDuplicates)
// filteredItems: number[] => [1, 2, 3, 5, 8]
```
### filterDuplicatesByKey
Removes duplicates from an array by its key. Only the first occurrence of an item will be kept.
> Motivation: It is less error-prone if you can only pass the keys an object provides to a filter function. With this function you get full types support.
#### Usage
```TypeScript
import { filterDuplicatesByKey } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [
{ id: 1, name: 'name-1' },
{ id: 2, name: 'name-2' },
{ id: 3, name: 'name-1' },
{ id: 4, name: 'name-2' }
]
const filteredItems = items.filter(filterDuplicatesByKey('name'))
// filteredItems: Product[] => [{ id: 1, name: 'name-1' }, { id: 2, name: 'name-2' }]
const willThrowAnError = items.filter(filterDuplicatesByKey('price'))
// throws: Argument of type '"price"' is **not** assignable to parameter of type '"id" | "name"'
```
### and
Combines (`&&`) multiple filter functions.
#### Usage
```TypeScript
import { and, isString } from 'typesafe-utils'
const items = [null, "test", undefined, "hi"]
const isShortString = and(isString, (value) => value.length < 3)
const filteredItems = items.filter(isShortString)
// filteredItems: string[] => ['hi']
```
### or
Combines (`||`) multiple filter functions.
#### Usage
```TypeScript
import { or } from 'typesafe-utils'
const items = [10, 2, 3, 5, 8, 1]
const isFiveOrTen = or((value) => value === 5, (value) => value === 10)
const filteredItems = items.filter(isFiveOrTen)
// filteredItems: number[] => [10, 5]
```
### not
Inverts a filter function.
#### Usage
```TypeScript
import { not, filterDuplicates } from 'typesafe-utils'
type Product = {
id: number
name: string
}
const items: Product[] = [
{ id: 1, name: 'name-1' },
{ id: 2, name: 'name-2' },
{ id: 3, name: 'name-1' },
{ id: 4, name: 'name-2' }
]
const filteredItems = items.filter(not(filterDuplicatesByKey('name')))
// filteredItems: Product[] => [{ id: 3, name: 'name-1' }, { id: 4, name: 'name-2' }]
// The `not` function takes two optional type arguments.
// The first is the type you expect the filter function to return.
// The second is the Type of the Array you want to filter.
// e.g.
const notNull = [1, 5, null].filter(not((value => value === null)))
// notNull: number[] => [1, 5]
```
### createFilter
Creates a typeguard filter.
#### Usage
```TypeScript
import { createFilter } from 'typesafe-utils'
interface Item {
id: number
}
interface ItemWithName extends Item {
name: string
}
const items: (Item | ItemWithName | undefined)[] = [
{ id: 1 },
undefined
{ id: 3, name: 'name-1' },
{ id: 4 }
]
const filterHasName = createFilter((item) => !!item?.name)
const filteredItems = items.filter(filterHasName)
// filteredItems: ItemWithName[] => [{ id: 3, name: 'name-1' }]
```
## sorting functions
### sortNumberASC
sort `number` in **ASC** order
#### Usage
```TypeScript
import { sortNumberASC } from 'typesafe-utils'
const items = [4, -1, 3, 0]
const result = items.sort(sortNumberASC)
// result: number[] => [-1, 0, 3, 4]
```
### sortNumberDESC
sort `number` in **DESC** order
#### Usage
```TypeScript
import { sortNumberDESC } from 'typesafe-utils'
const items = [2, -5, 0]
const result = items.sort(sortNumberDESC)
// result: number[] => [2, 0, -5]
```
### sortNumberPropertyASC
sort property of type `number` in **ASC** order
#### Usage
```TypeScript
import { sortNumberPropertyASC } from 'typesafe-utils'
type Car {
speed: number
}
const items: Car[] = [
{ speed: 113 },
{ speed: 100 },
{ speed: 95 }
]
const result = items.sort(sortNumberPropertyASC('speed'))
// result: Car[] => [{ speed: 95 }, { speed: 100 }, { speed: 113 }}
```
### sortNumberPropertyDESC
sort property of type `number` in **DESC** order
#### Usage
```TypeScript
import { sortNumberPropertyDESC } from 'typesafe-utils'
type Car {
speed: number
}
const items: Car[] = [
{ speed: 70 }
{ speed: 87 }
]
const result = items.sort(sortNumberPropertyDESC('speed'))
// result: Car[] => [{ speed: 87 }, { speed: 70 }]
```
### sortStringASC
sort `string` in **ASC** order
#### Usage
```TypeScript
import { sortStringASC } from 'typesafe-utils'
const items = ['Hi', 'apples']
const result = items.sort(sortStringASC)
// result: string[] => ['apples', Hi']
```
### sortStringDESC
sort `string` in **DESC** order
#### Usage
```TypeScript
import { sortStringDESC } from 'typesafe-utils'
const items = ['apple', 'banana']
const result = items.sort(sortStringDESC)
// result: string[] => ['banana', 'apple']
```
### sortStringPropertyASC
sort property of type `string` in **ASC** order
#### Usage
```TypeScript
import { sortStringPropertyASC } from 'typesafe-utils'
type Car {
color: string
}
const items: Car[] = [
{ color: 'green' },
{ color: 'brown' }
]
const result = items.sort(sortStringPropertyASC('color'))
// result: Car[] => [{ color: 'brown' }, { color: 'green' }]
```
### sortStringPropertyDESC
sort property of type `string` in **DESC** order
#### Usage
```TypeScript
import { sortStringPropertyDESC } from 'typesafe-utils'
type Car {
color: string
}
const items: Car[] = [
{ color: 'red' },
{ color: 'blue' }
]
const result = items.sort(sortStringPropertyDESC('color'))
// result: Car[] => [{ color: 'red' }, { color: 'blue' }]
```
### sortDateASC
sort `Date` in **ASC** order
#### Usage
```TypeScript
import { sortDateASC } from 'typesafe-utils'
const today = new Date()
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000)
const items = [tomorrow, today]
const result = items.sort(sortDateASC)
// result: Date[] => [today, tomorrow]
```
### sortDateDESC
sort `Date` in **DESC** order
#### Usage
```TypeScript
import { sortDateDESC } from 'typesafe-utils'
const today = new Date()
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000)
const items = [today, tomorrow]
const result = items.sort(sortDateDESC)
// result: Date[] => [tomorrow, today]
```
### sortDatePropertyASC
sort property of type `Date` in **ASC** order
#### Usage
```TypeScript
import { sortDatePropertyASC } from 'typesafe-utils'
type Smartphone = {
releaseDate: Date
}
const today = new Date()
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000)
const items: Smartphone[] = [
{ releaseDate: tomorrow },
{ releaseDate: today }
]
const items: Smartphone[] = []
const result = items.sort(sortDatePropertyASC('releaseDate'))
// result: Smartphone[]=> [{ releaseDate: today }, { releaseDate: tomorrow }]
```
### sortDatePropertyDESC
sort property of type `Date` in **DESC** order
#### Usage
```TypeScript
import { sortDatePropertyDESC } from 'typesafe-utils'
type Smartphone = {
releaseDate: Date
}
const today = new Date()
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000)
const items: Smartphone[] = [
{ releaseDate: today },
{ releaseDate: tomorrow }
]
const result = items.sort(sortDatePropertyDESC('releaseDate'))
// result: Smartphone[] => [{ releaseDate: tomorrow }, { releaseDate: today }]
```
## mapping functions
### pick
Picks an attribute from an Object.
#### Usage
```TypeScript
import { pick } from 'typesafe-utils'
interface Item {
id: number
name: string
price: number
}
const items: Item[] = [
{ id: 1, name: '', price: 123 },
{ id: 3, name: '', price: 0 },
{ id: 7, name: '', price: 12 },
]
const ids = items.map(pick('id'))
// ids: number[] => [ 1, 3, 7 ]
```
## other
### deepClone
Creates a deep copy of an object containing primitive values.
> Motivation: I have seen a variety of clone-functions that return any. There you would need to always specify the type by ourself. Using this function, you will get a correctly typed object back.
#### Usage
```TypeScript
import { deepClone } from 'typesafe-utils'
const objectToClone: MyTypedObject = { ... }
const clonedObject = deepClone(objectToClone)
// => clonedObject: MyTypedObject => { ... }
```
### uniqueArray
Removes duplicates from an array.
#### Usage
```TypeScript
import { uniqueArray } from 'typesafe-utils'
const unique = uniqueArray('John', 'Max', 'John')
// => unique: string[] => ['John', 'Max']
```
## Types
### Truthy
Contains all `Truthy` values (everything excluding [Falsy](#falsy) values)
#### Usage
```TypeScript
import { Truthy } from 'typesafe-utils'
export const isTruthy = (value: T): value is Truthy => !!value
const truthy = [123, undefined].filter(isTruthy) // => number[]
const notTruthy = [false, true].filter(isTruthy) // => never[]
```
### Falsy
Contains all `Falsy` values (false | '' | 0 | null | undefined)
#### Usage
```TypeScript
import { Falsy } from 'typesafe-utils'
export const isFalsy = (value: T): value is Falsy => !value
const falsy = [undefined, ''].filter(isFalsy) // => undefined[]
const notFalsy = [0, ''].filter(isFalsy) // => never[]
```
### TypeGuard
### TypeGuardWithReturnType
Allows you to write custom `TypeGuard` functions.
#### Usage
```TypeScript
import { TypeGuard } from 'typesafe-utils'
type Project {
id: number
// ...
}
const isProject = (value: T): value is TypeGuard => value?.hasOwnProperty('id')
const p1 = isProject({ id: 1 }) // => true
const p2 = isProject(true) // => false
```
### TypeGuardInverted
### TypeGuardInvertedWithReturnType
Allows you to write custom inverted `TypeGuard` functions.
#### Usage
```TypeScript
import { TypeGuardInverted } from 'typesafe-utils'
type Project {
id: number
// ...
}
const isNotProject = (value: T): value is TypeGuardInverted => !value?.hasOwnProperty('id')
const p1 = isNotProject({ id: 1 }) // => false
const p2 = isNotProject(null) // => true
```