Comparing version 2.2.1 to 2.3.0
@@ -11,6 +11,38 @@ 'use strict'; | ||
if: createUnpack(record), | ||
match | ||
match: (a, b) => b ? evalMatch(a, b) : val => evalMatch(val, a), | ||
matchWith: (_other, // yep, it is only used to "remember" type | ||
matchObj) => createMatchTupleFunction(matchObj) | ||
}, createConstructors(record, typeof recOrFunc === 'function')); | ||
}; | ||
const createMatchTupleFunction = matchObj => { | ||
const { | ||
default: def | ||
} = matchObj; | ||
return function matchTuple(a, b) { | ||
const { | ||
p0: valA, | ||
k: keyA | ||
} = a; | ||
const { | ||
p0: valB, | ||
k: KeyB | ||
} = b; | ||
if (keyA in matchObj) { | ||
const inner = matchObj[keyA]; | ||
if (inner !== undefined && KeyB in inner) { | ||
const matchedFunction = inner[KeyB]; | ||
if (matchedFunction !== undefined) { | ||
return matchedFunction(valA, valB); | ||
} | ||
} | ||
} | ||
return def(a, b); | ||
}; | ||
}; | ||
const evalMatch = (val, cases) => { | ||
@@ -22,4 +54,2 @@ // first elem is always the key | ||
const match = (a, b) => b ? evalMatch(a, b) : val => evalMatch(val, a); | ||
const createConstructors = (rec, isGeneric) => { | ||
@@ -26,0 +56,0 @@ const result = {}; // tslint:disable-next-line: forin |
export const of = ((val) => val); | ||
export const Union = (recOrFunc) => { | ||
const record = typeof recOrFunc === 'function' | ||
? recOrFunc(undefined) | ||
: recOrFunc; | ||
const record = typeof recOrFunc === 'function' ? recOrFunc(undefined) : recOrFunc; | ||
// tslint:disable-next-line:prefer-object-spread | ||
return Object.assign({ if: createUnpack(record), match }, createConstructors(record, typeof recOrFunc === 'function')); | ||
return Object.assign({ | ||
if: createUnpack(record), | ||
match: (a, b) => (b ? evalMatch(a, b) : (val) => evalMatch(val, a)), | ||
matchWith: (_other, // yep, it is only used to "remember" type | ||
matchObj) => createMatchTupleFunction(matchObj), | ||
}, createConstructors(record, typeof recOrFunc === 'function')); | ||
}; | ||
const createMatchTupleFunction = (matchObj) => { | ||
const { default: def } = matchObj; | ||
return function matchTuple(a, b) { | ||
const { p0: valA, k: keyA } = a; | ||
const { p0: valB, k: KeyB } = b; | ||
if (keyA in matchObj) { | ||
const inner = matchObj[keyA]; | ||
if (inner !== undefined && KeyB in inner) { | ||
const matchedFunction = inner[KeyB]; | ||
if (matchedFunction !== undefined) { | ||
return matchedFunction(valA, valB); | ||
} | ||
} | ||
} | ||
return def(a, b); | ||
}; | ||
}; | ||
const evalMatch = (val, cases) => { | ||
@@ -14,3 +34,2 @@ // first elem is always the key | ||
}; | ||
const match = (a, b) => b ? evalMatch(a, b) : (val) => evalMatch(val, a); | ||
const createConstructors = (rec, isGeneric) => { | ||
@@ -69,2 +88,2 @@ const result = {}; | ||
const arity = (p0, p1, p2) => p2 !== undefined ? 3 : p1 !== undefined ? 2 : p0 !== undefined ? 1 : 0; | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBMkNBLE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FBVSxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQVEsQ0FBQztBQThOcEQsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFjLENBQzlCLFNBQWtDLEVBQ2xDLEVBQUU7SUFDRixNQUFNLE1BQU0sR0FDVixPQUFPLFNBQVMsS0FBSyxVQUFVO1FBQzdCLENBQUMsQ0FBQyxTQUFTLENBQUUsU0FBZ0MsQ0FBQztRQUM5QyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBRWhCLGdEQUFnRDtJQUNoRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQ2xCLEVBQUUsRUFBRSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFDbkMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLE9BQU8sU0FBUyxLQUFLLFVBQVUsQ0FBQyxDQUNyRCxDQUFDO0FBQ1gsQ0FBQyxDQUFDO0FBRUYsTUFBTSxTQUFTLEdBQUcsQ0FDaEIsR0FBUSxFQUNSLEtBQWtDLEVBQzdCLEVBQUU7SUFDUCwrQkFBK0I7SUFDL0IsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBUSxDQUFDO0lBQzFDLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDOUUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQXVCLENBQUMsQ0FBTSxFQUFFLENBQU8sRUFBRSxFQUFFLENBQ3BELENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFD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Q25CLEtBQUssQ0FBQztZQUNKLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLEtBQUssQ0FBQztZQUNKLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7S0FDcEM7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQVUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNyQyx5Q0FBeUM7QUFFekMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxFQUFPLEVBQUUsRUFBTyxFQUFFLEVBQU8sRUFBVSxFQUFFLENBQ2xELEVBQUUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyJ9 | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBa0RBLE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FBVSxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQVEsQ0FBQztBQThOcEQsTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFjLENBQzlCLFNBQWtDLEVBQ2xDLEVBQUU7SUFDRixNQUFNLE1BQU0sR0FDVixPQUFPLFNBQVMsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBRSxTQUFnQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUU3RixnREFBZ0Q7SUFDaEQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQjtRQUNFLEVBQUUsRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDO1FBQ3hCLEtBQUssRUFBRSxDQUFDLENBQU0sRUFBRSxDQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRixTQUFTLEVBQUUsQ0FDVCxNQUF3QixFQUFFLDBDQUEwQztRQUNwRSxRQUE0QyxFQUM1QyxFQUFFLENBQUMsd0JBQXdCLENBQUMsUUFBUSxDQUFDO0tBQ3hDLEVBQ0Qsa0JBQWtCLENBQUMsTUFBTSxFQUFFLE9BQU8sU0FBUyxLQUFLLFVBQVUsQ0FBQyxDQUNyRCxDQUFDO0FBQ1gsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxDQUsvQixRQUF3QyxFQUN4QyxFQUFFO0lBQ0YsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxRQUFRLENBQUM7SUFDbEMsT0FBTyxTQUFTLFVBQVUsQ0FBQyxDQUFjLEVBQUUs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 |
@@ -14,2 +14,6 @@ export interface Const<T> { | ||
} | ||
export declare type SingleDataCase = Of<[Unit]> | Const<unknown> | Of<[unknown]>; | ||
export interface SingleDataRecordDict { | ||
readonly [key: string]: SingleDataCase; | ||
} | ||
export interface ForbidDefault { | ||
@@ -21,5 +25,7 @@ default?: never; | ||
readonly match?: never; | ||
readonly matchWith?: never; | ||
readonly T?: never; | ||
} & ForbidDefault; | ||
export declare type RequiredRecordType = RecordDict & ForbidReservedProps; | ||
export declare type SingleDataRecordType = SingleDataRecordDict & ForbidReservedProps; | ||
export interface Of<T> { | ||
@@ -110,8 +116,10 @@ _opaque: T; | ||
}; | ||
export declare type UnionObj<Rec> = { | ||
match: MatchFunc<Rec>; | ||
declare type UnionDesc<Rec> = { | ||
if: Unpack<Rec>; | ||
T: UnionVal<Rec>; | ||
match: MatchFunc<Rec>; | ||
matchWith: Rec extends SingleDataRecordType ? <Other extends SingleDataRecordType, Result>(other: UnionDesc<Other>, matchObj: MatchCasesForTwo<Rec, Other, Result>) => (a: UnionVal<Rec>, b: UnionVal<Other>) => Result : never; | ||
} & Constructors<Rec>; | ||
export declare type GenericUnionObj<Rec> = { | ||
export declare type UnionObj<Rec> = UnionDesc<Rec>; | ||
export declare type GenericUnionDesc<Rec> = { | ||
match: MatchFuncG<Rec>; | ||
@@ -121,6 +129,17 @@ if: UnpackG<Rec>; | ||
} & ConstructorsG<Rec>; | ||
declare type TypeOfLeg<Leg> = Leg extends Of<infer A> ? A extends [void] | [Unit] ? void : A extends [infer Value] ? Value : A extends Const<infer C> ? C : never : never; | ||
export declare type MatchCaseFuncTwo<LegA, LegB, Res> = (a: TypeOfLeg<LegA>, b: TypeOfLeg<LegB>) => Res; | ||
export declare type CasesTwo<RecordA, RecordB, Result> = { | ||
[KA in keyof RecordA]?: { | ||
[KB in keyof RecordB]?: MatchCaseFuncTwo<RecordA[KA], RecordB[KB], Result>; | ||
}; | ||
}; | ||
export declare type MatchCasesForTwo<RecordA, RecordB, Result> = CasesTwo<RecordA, RecordB, Result> & { | ||
default: (a: UnionVal<RecordA>, b: UnionVal<RecordB>) => Result; | ||
}; | ||
export interface UnionFunc { | ||
<R extends RequiredRecordType>(record: R): UnionObj<R>; | ||
<R extends RequiredRecordType>(ctor: (g: Generic) => R): GenericUnionObj<R>; | ||
<R extends RequiredRecordType>(record: R): UnionDesc<R>; | ||
<R extends RequiredRecordType>(ctor: (g: Generic) => R): GenericUnionDesc<R>; | ||
} | ||
export declare const Union: UnionFunc; | ||
export {}; |
const of = ((val) => val); | ||
const Union = (recOrFunc) => { | ||
const record = typeof recOrFunc === 'function' | ||
? recOrFunc(undefined) | ||
: recOrFunc; | ||
const record = typeof recOrFunc === 'function' ? recOrFunc(undefined) : recOrFunc; | ||
// tslint:disable-next-line:prefer-object-spread | ||
return Object.assign({ if: createUnpack(record), match }, createConstructors(record, typeof recOrFunc === 'function')); | ||
return Object.assign({ | ||
if: createUnpack(record), | ||
match: (a, b) => (b ? evalMatch(a, b) : (val) => evalMatch(val, a)), | ||
matchWith: (_other, // yep, it is only used to "remember" type | ||
matchObj) => createMatchTupleFunction(matchObj), | ||
}, createConstructors(record, typeof recOrFunc === 'function')); | ||
}; | ||
const createMatchTupleFunction = (matchObj) => { | ||
const { default: def } = matchObj; | ||
return function matchTuple(a, b) { | ||
const { p0: valA, k: keyA } = a; | ||
const { p0: valB, k: KeyB } = b; | ||
if (keyA in matchObj) { | ||
const inner = matchObj[keyA]; | ||
if (inner !== undefined && KeyB in inner) { | ||
const matchedFunction = inner[KeyB]; | ||
if (matchedFunction !== undefined) { | ||
return matchedFunction(valA, valB); | ||
} | ||
} | ||
} | ||
return def(a, b); | ||
}; | ||
}; | ||
const evalMatch = (val, cases) => { | ||
@@ -14,3 +34,2 @@ // first elem is always the key | ||
}; | ||
const match = (a, b) => b ? evalMatch(a, b) : (val) => evalMatch(val, a); | ||
const createConstructors = (rec, isGeneric) => { | ||
@@ -17,0 +36,0 @@ const result = {}; |
{ | ||
"name": "ts-union", | ||
"description": "ADT (sum type) in typescript inspired by ML language family", | ||
"version": "2.2.1", | ||
"version": "2.3.0", | ||
"license": "MIT", | ||
@@ -20,5 +20,2 @@ "files": [ | ||
"devDependencies": { | ||
"@babel/plugin-transform-modules-commonjs": "^7.10.1", | ||
"@babel/preset-env": "^7.10.2", | ||
"@babel/preset-typescript": "^7.10.1", | ||
"@pika/pack": "^0.5.0", | ||
@@ -29,7 +26,6 @@ "@pika/plugin-build-node": "^0.9.2", | ||
"@types/node": "^14.0.11", | ||
"@types/jest": "25.2.3", | ||
"jest": "^26.0.0", | ||
"ts-jest": "^26.1.0", | ||
"typescript": "3.9.5", | ||
"ts-node": "^8.10.2", | ||
"ava": "^3.13.0", | ||
"prettier": "^2.1.2", | ||
"ts-node": "^9.0.0", | ||
"typescript": "4.0.3", | ||
"unionize": "3.1.0" | ||
@@ -36,0 +32,0 @@ }, |
103
README.md
@@ -87,2 +87,105 @@ # ts-union | ||
### **EXPERIMENTAL** `matchWith` | ||
WARNING: This API is experimental and currently more of an MVP. | ||
Often we want to match a union with another union. A good example of this if we try to model a state transition in `useReducer` in React or model a state machine. | ||
This is what you have to do currently: | ||
```ts | ||
const State = Union({ | ||
Loading: of(null), | ||
Loaded: of<number>(), | ||
Err: of<string>(), | ||
}); | ||
const Ev = Union({ | ||
ErrorHappened: of<string>(), | ||
DataFetched: of<number>(), | ||
}); | ||
const { Loaded, Err, Loading } = State; | ||
const transition = (prev: typeof State.T, ev: typeof Ev.T) => | ||
State.match(prev, { | ||
Loading: () => | ||
Ev.match(ev, { | ||
ErrorHappened: (err) => Err(err), | ||
DataFetched: (data) => Loaded(data), | ||
}), | ||
Loaded: (loadedData) => | ||
// just add to the current loaded value as an example | ||
Ev.if.DataFetched( | ||
ev, | ||
(data) => Loaded(loadedData + data), | ||
() => prev | ||
), | ||
default: (s) => s, | ||
}); | ||
``` | ||
It gets worse and more verbose when complexity grows, also you have to match the `Ev` in each variant of `State`. | ||
In my experience this comes up often enough to justify a dedicated API for matching a pair: | ||
```ts | ||
import { Union, of } from 'ts-union'; | ||
const State = Union({ | ||
Loading: of(null), | ||
Loaded: of<number>(), | ||
Err: of<string>(), | ||
}); | ||
const Ev = Union({ | ||
ErrorHappened: of<string>(), | ||
DataFetched: of<number>(), | ||
}); | ||
const { Loaded, Err, Loading } = State; | ||
const transition = State.matchWith(Ev, { | ||
Loading: { | ||
ErrorHappened: (_, err) => Err(err), | ||
DataFetched: (_, data) => Loaded(data), | ||
}, | ||
Loaded: { | ||
DataFetched: (loaded, data) => Loaded(loaded + data), | ||
}, | ||
default: (prevState, ev) => prevState, | ||
}); | ||
// usage | ||
const newState = transition(Loading, Ev.ErrorHappened('oops')); // <-- State.Err('oops') | ||
``` | ||
`transition` is a function with type signature: (prev: State, ev: Ev) => State. | ||
Note that the return type is **inferred**, meaning that you can return whatever type you want :) | ||
```ts | ||
const logLoadingTransition = State.matchWith(Ev, { | ||
Loading: { | ||
ErrorHappened: (_, err) => 'Oops, error happened: ' + err, | ||
DataFetched: (_, data) => 'Data loaded with: ' + data.toString(), | ||
}, | ||
default: () => '', | ||
}); | ||
``` | ||
#### Caveats | ||
1. Doesn't support generic version (yet?) | ||
2. Doesn't work with unions that have more than 1 arguments in variants. E.g. `of<string, number>()` will give an incomprehensible type error. | ||
3. You cannot pass additional data to the update function. I'm tinkering about something like this for the future releases: | ||
```ts | ||
const transition = State.matchWith(Ev, {...}, of<SomeContext>()); | ||
transition = (prev, ev, someContextValue); | ||
``` | ||
### Two ways to specify variants with no payload | ||
@@ -89,0 +192,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
88212
10
11
657
530