Add support for $Diff
parent
72277118d5
commit
0408a93927
|
@ -135,6 +135,39 @@ function values(params: (?Type)[], resolve: TypeId => Type): ?Type {
|
||||||
return t.createUnion(variants);
|
return t.createUnion(variants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function diff(params: (?Type)[], resolve: TypeId => Type): ?Type {
|
||||||
|
invariant(params.length === 2);
|
||||||
|
|
||||||
|
let [minuend, subtrahend] = params;
|
||||||
|
|
||||||
|
invariant(minuend && subtrahend);
|
||||||
|
invariant(minuend.kind === 'reference');
|
||||||
|
|
||||||
|
minuend = resolve(minuend.to);
|
||||||
|
|
||||||
|
invariant(minuend.kind === 'record');
|
||||||
|
|
||||||
|
if (subtrahend.kind === 'reference') {
|
||||||
|
subtrahend = resolve(subtrahend.to);
|
||||||
|
}
|
||||||
|
|
||||||
|
invariant(subtrahend.kind === 'record');
|
||||||
|
|
||||||
|
// TODO: more clever subtraction.
|
||||||
|
const blacklist = wu(subtrahend.fields).pluck('name').toArray();
|
||||||
|
|
||||||
|
const fields = wu(minuend.fields)
|
||||||
|
.filter(field => !blacklist.includes(field.name))
|
||||||
|
.map(field => ({
|
||||||
|
name: field.name,
|
||||||
|
value: t.clone(field.value),
|
||||||
|
required: field.required,
|
||||||
|
}))
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
return t.createRecord(fields);
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Object: object,
|
Object: object,
|
||||||
Buffer: buffer,
|
Buffer: buffer,
|
||||||
|
@ -148,7 +181,7 @@ export default {
|
||||||
$Exact: unwrap, // TODO: another semantic for exact types?
|
$Exact: unwrap, // TODO: another semantic for exact types?
|
||||||
$Keys: keys,
|
$Keys: keys,
|
||||||
$Values: values,
|
$Values: values,
|
||||||
// TODO: $Diff
|
$Diff: diff,
|
||||||
// TODO: $All
|
// TODO: $All
|
||||||
// TODO: $Either
|
// TODO: $Either
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
type A = {
|
||||||
|
x: string,
|
||||||
|
y: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
type B = {
|
||||||
|
y: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
type X = $Diff<A, B>;
|
||||||
|
type Y = $Diff<A, {x: string}>;
|
||||||
|
|
||||||
|
export {X, Y};
|
|
@ -0,0 +1,27 @@
|
||||||
|
- kind: record
|
||||||
|
fields:
|
||||||
|
- name: x
|
||||||
|
value: {kind: string}
|
||||||
|
required: true
|
||||||
|
- name: y
|
||||||
|
value: {kind: boolean}
|
||||||
|
required: true
|
||||||
|
id: [diffs, A]
|
||||||
|
- kind: record
|
||||||
|
fields:
|
||||||
|
- name: y
|
||||||
|
value: {kind: boolean}
|
||||||
|
required: true
|
||||||
|
id: [diffs, B]
|
||||||
|
- kind: record
|
||||||
|
fields:
|
||||||
|
- name: x
|
||||||
|
value: {kind: string}
|
||||||
|
required: true
|
||||||
|
id: [diffs, X]
|
||||||
|
- kind: record
|
||||||
|
fields:
|
||||||
|
- name: y
|
||||||
|
value: {kind: boolean}
|
||||||
|
required: true
|
||||||
|
id: [diffs, Y]
|
Loading…
Reference in New Issue