Skip to content

Instantly share code, notes, and snippets.

@fvilante
Last active March 26, 2019 01:31
Show Gist options
  • Select an option

  • Save fvilante/9d134bd133978c2e53d747020696ab7f to your computer and use it in GitHub Desktop.

Select an option

Save fvilante/9d134bd133978c2e53d747020696ab7f to your computer and use it in GitHub Desktop.
import { mapObjIndexed } from 'ramda'
type PropMorphism
<TKeyValue, TContext extends object, TKeyName, TResult> =
(value: TKeyValue, context: TContext, keyname: TKeyName) =>
TResult
/**
* Use HasExactlySameKeys if you want to assure to procced
* only if keys are equals
*/
type ObjectMorphism<T extends object, U extends object> = {
[K in (keyof T & keyof U)]:
PropMorphism<T[K], T, K, U[K]>
}
type ObjectMapper =
<A extends object, B extends object>
(ofn: ObjectMorphism<A,B>) => (o: A) => B
/**
* Maps an interfaced-object to other interfaced-object using a
* infered-object-morphism
*
* IMPORTANT: You SHOULD type annotate source interface, destination interface and
* the object-morphism you create to map source to destination.
*
* - morphism object and source object must have exactly same keys
* - destination object must have at least same keys of source object
* - if destination object has more keys than source exceding keys
* will be trunc
*
* @param objectMorphism object morphism: must contains same property as
* source object, and the type of each property must be a PropMorphism
* @param obj source object to be mapped
*/
const objectMapper: ObjectMapper =
objectMorphism => obj => {
const proccessEachKey = (value, key) =>
objectMorphism[key](value)
const result = mapObjIndexed(proccessEachKey, obj)
return result
}
// ------------ Example of use ------------------
interface A {
readonly a: number
readonly b: string
readonly c: boolean
//readonly d: boolean
}
interface B {
readonly a: number
readonly b: boolean
readonly c: boolean
//readonly d: boolean
}
const morphism: ObjectMorphism<A, B> = {
a: val => val+2,
b: val => val==="foo",
c: val => val,
}
const a:A = {
a: 2,
b: "bar",
c: false,
}
const b = objectMapper(morphism)(a)
console.log(a,b,morphism)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment