Add support for $All and $Either

master
Paul Loyd 2017-12-03 14:57:44 +03:00
parent 5d406112e5
commit 57603cf0ff
6 changed files with 125 additions and 2 deletions

View File

@ -178,6 +178,24 @@ function diff(params: (?Type)[], resolve: TypeId => Type): ?Type {
return t.createRecord(fields);
}
// $All<M, S>.
function all(params: (?Type)[]): ?Type {
const parts = wu(params).filter().toArray();
return parts.length === 0 ? null
: parts.length === 1 ? parts[0]
: t.createIntersection(parts);
}
// $Either<M, S>.
function either(params: (?Type)[]): ?Type {
const variants = wu(params).filter().toArray();
return variants.length === 0 ? null
: variants.length === 1 ? variants[0]
: t.createUnion(variants);
}
export default {
Object: object,
Buffer: buffer,
@ -192,6 +210,6 @@ export default {
$Keys: keys,
$Values: values,
$Diff: diff,
// TODO: $All
// TODO: $Either
$All: all,
$Either: either,
};

View File

@ -0,0 +1,16 @@
type A = {a: number};
type B = {b: string};
type C = {c: boolean};
type X = $All<A, B>;
type Y = {
y: $All<A, B, C>,
yy: $All<() => boolean, () => string>,
};
class Z {
z: $All<A, () => void>;
}
export {X, Y, Z};

View File

@ -0,0 +1,47 @@
- kind: record
fields:
- name: a
value: {kind: number, repr: f64}
required: true
id: [all, A]
- kind: record
fields:
- name: b
value: {kind: string}
required: true
id: [all, B]
- kind: intersection
parts:
- kind: reference
to: [all, A]
- kind: reference
to: [all, B]
id: [all, X]
- kind: record
fields:
- name: c
value: {kind: boolean}
required: true
id: [all, C]
- kind: record
fields:
- name: y
value:
kind: intersection
parts:
- kind: reference
to: [all, A]
- kind: reference
to: [all, B]
- kind: reference
to: [all, C]
required: true
id: [all, Y]
- kind: record
fields:
- name: z
value:
kind: reference
to: [all, A]
required: true
id: [all, Z]

View File

@ -0,0 +1,14 @@
type Type = {
a: $Either<string, boolean>,
};
interface Interface {
a: $Either<string, boolean, number>;
aa: $Either<() => number, () => boolean>;
}
class Class {
a: $Either<string, () => void>;
}
export {Type, Interface, Class};

View File

@ -0,0 +1,27 @@
- kind: record
fields:
- name: a
value:
kind: union
variants:
- {kind: string}
- {kind: boolean}
required: true
id: [either, Type]
- kind: record
fields:
- name: a
value:
kind: union
variants:
- {kind: string}
- {kind: boolean}
- {kind: number, repr: f64}
required: true
id: [either, Interface]
- kind: record
fields:
- name: a
value: {kind: string}
required: true
id: [either, Class]

View File

@ -1,3 +1,4 @@
// TODO: disassembly the test.
type Type = {
a: string,