Skip to content

Instantly share code, notes, and snippets.

@bag-man
Last active October 25, 2019 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bag-man/df61980a4e7d24ed4cd311f6bd49bd17 to your computer and use it in GitHub Desktop.
Save bag-man/df61980a4e7d24ed4cd311f6bd49bd17 to your computer and use it in GitHub Desktop.
Generate recursive typed functions
import { deepEqual } from 'assert'
type RecursiveFn<T> = (xs: T[], out?: T[]) => T[]
type OperatorFn<T> = (T: T, xs: T[], out: T[]) => T | void
type FactoryFn = <T>(fn: OperatorFn<T>) => RecursiveFn<T>
const recursiveFactory: FactoryFn = <T>(fn: OperatorFn<T>) => {
const recursive: RecursiveFn<T> = (xs, out = []) => {
const x = xs.shift()
const res = fn(x, xs, out)
if (res) {
out.push(res)
}
if (xs.length) {
return recursive(xs, out)
}
return out
}
return recursive
}
interface Status {
id: string;
effectiveDate: string;
type: string;
}
const reduceStatuses: OperatorFn<Status> = (x, _xs, out) => {
if (out.some(n => n.effectiveDate === x.effectiveDate && n.type === x.type)) {
return
}
return x
}
const reducer = recursiveFactory<Status>(reduceStatuses)
const input = [
{
id: '2e7c0c2b-9238-46cc-80ed-1e6cda05a1ca',
effectiveDate: '2019-10-01',
type: 'ACTIVE'
},
{
id: '60a93504-23bc-4f17-a4e3-d8e069c4600c',
effectiveDate: '2019-11-01',
type: 'TERMINATED'
},
{
id: 'b544ddde-3593-46a9-8280-8d4139bc261e',
effectiveDate: '2019-10-01',
type: 'ACTIVE'
}
]
const expected = [
{
id: '2e7c0c2b-9238-46cc-80ed-1e6cda05a1ca',
effectiveDate: '2019-10-01',
type: 'ACTIVE'
},
{
id: '60a93504-23bc-4f17-a4e3-d8e069c4600c',
effectiveDate: '2019-11-01',
type: 'TERMINATED'
},
]
const output = reducer(input)
deepEqual(output, expected)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment