Advertisement
Guest User

Untitled

a guest
Mar 19th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 0.72 KB | None | 0 0
  1. // Definition
  2.  
  3. type Compact<A> = { [k in keyof A]: A[k] }
  4.  
  5. type FStruct<R extends Record<any, any>, K extends keyof R = keyof R> = {
  6. [k in K]: { [kv in R[k]]: R extends { [r in k]: kv } ? Compact<R> : never }
  7. }
  8.  
  9. type Match<StructK, R> = { [KV in keyof StructK]: (v: StructK[KV]) => R }
  10.  
  11. const folder = <A extends object>() => <D extends keyof A>(discr: D) => <R>(match: Match<FStruct<A>[D], R>) => (a: A) =>
  12. match[a[discr]](a as any)
  13.  
  14. // Usage
  15.  
  16. type A = { type: 'ta'; x: 'a' } | { type: 'tb'; x: 'b'; y: 'c' } // Adhoc Union
  17.  
  18. const aByType = folder<A>()('type') // Define the discriminant
  19.  
  20. const matcher = aByType({ // a Matcher function
  21. ta: v => v.x,
  22. tb: v => v.y
  23. })
  24.  
  25. const res = matcher({ type: 'ta', x: 'a' }) // Application
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement