Skip to content

Commit 5dbf90e

Browse files
committed
feat: add intersection, tuple, and union builders
1 parent 89264d8 commit 5dbf90e

File tree

4 files changed

+106
-24
lines changed

4 files changed

+106
-24
lines changed

src/index.ts

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,90 @@ export const record = <K extends string | number | symbol, V>(
8181
): Type<Record<K, V>> =>
8282
new ObjectType([], [new ObjectTypeIndexer('key', key, value)]) as any
8383

84-
type Tag = {
85-
Key: string
86-
Value: string
87-
PropagateAtLaunch?: boolean | null | undefined
88-
}
89-
90-
const TagType = object<Tag>({
91-
Key: string(),
92-
Value: string(),
93-
PropagateAtLaunch: nullable(boolean()),
94-
})
84+
export const tuple = <T extends []>(
85+
types: { [Index in keyof T]: Type<T[Index]> }
86+
): Type<T> => new TupleType(types) as any
9587

96-
const TagsType = new ArrayType(TagType)
88+
export function intersection<T1>(...types: [Type<T1>]): Type<T1>
89+
export function intersection<T1, T2>(
90+
...types: [Type<T1>, Type<T2>]
91+
): Type<T1 & T2>
92+
export function intersection<T1, T2, T3>(
93+
...types: [Type<T1>, Type<T2>, Type<T3>]
94+
): Type<T1 & T2 & T3>
95+
export function intersection<T1, T2, T3, T4>(
96+
...types: [Type<T1>, Type<T2>, Type<T3>, Type<T4>]
97+
): Type<T1 & T2 & T3 & T4>
98+
export function intersection<T1, T2, T3, T4, T5>(
99+
...types: [Type<T1>, Type<T2>, Type<T3>, Type<T4>, Type<T5>]
100+
): Type<T1 & T2 & T3 & T4 & T5>
101+
export function intersection<T1, T2, T3, T4, T5, T6>(
102+
...types: [Type<T1>, Type<T2>, Type<T3>, Type<T4>, Type<T5>, Type<T6>]
103+
): Type<T1 & T2 & T3 & T4 & T5 & T6>
104+
export function intersection<T1, T2, T3, T4, T5, T6, T7>(
105+
...types: [
106+
Type<T1>,
107+
Type<T2>,
108+
Type<T3>,
109+
Type<T4>,
110+
Type<T5>,
111+
Type<T6>,
112+
Type<T7>
113+
]
114+
): Type<T1 & T2 & T3 & T4 & T5 & T6 & T7>
115+
export function intersection<T1, T2, T3, T4, T5, T6, T7, T8>(
116+
...types: [
117+
Type<T1>,
118+
Type<T2>,
119+
Type<T3>,
120+
Type<T4>,
121+
Type<T5>,
122+
Type<T6>,
123+
Type<T7>,
124+
Type<T8>
125+
]
126+
): Type<T1 & T2 & T3 & T4 & T5 & T6 & T7 & T8>
127+
export function intersection(...types: Type<any>[]): Type<any> {
128+
return new IntersectionType(types)
129+
}
97130

98-
TagsType.assert([{ Key: 'foo', Value: 'bar', Qux: 2 }])
131+
export function union<T1>(...types: [Type<T1>]): Type<T1>
132+
export function union<T1, T2>(...types: [Type<T1>, Type<T2>]): Type<T1 | T2>
133+
export function union<T1, T2, T3>(
134+
...types: [Type<T1>, Type<T2>, Type<T3>]
135+
): Type<T1 | T2 | T3>
136+
export function union<T1, T2, T3, T4>(
137+
...types: [Type<T1>, Type<T2>, Type<T3>, Type<T4>]
138+
): Type<T1 | T2 | T3 | T4>
139+
export function union<T1, T2, T3, T4, T5>(
140+
...types: [Type<T1>, Type<T2>, Type<T3>, Type<T4>, Type<T5>]
141+
): Type<T1 | T2 | T3 | T4 | T5>
142+
export function union<T1, T2, T3, T4, T5, T6>(
143+
...types: [Type<T1>, Type<T2>, Type<T3>, Type<T4>, Type<T5>, Type<T6>]
144+
): Type<T1 | T2 | T3 | T4 | T5 | T6>
145+
export function union<T1, T2, T3, T4, T5, T6, T7>(
146+
...types: [
147+
Type<T1>,
148+
Type<T2>,
149+
Type<T3>,
150+
Type<T4>,
151+
Type<T5>,
152+
Type<T6>,
153+
Type<T7>
154+
]
155+
): Type<T1 | T2 | T3 | T4 | T5 | T6 | T7>
156+
export function union<T1, T2, T3, T4, T5, T6, T7, T8>(
157+
...types: [
158+
Type<T1>,
159+
Type<T2>,
160+
Type<T3>,
161+
Type<T4>,
162+
Type<T5>,
163+
Type<T6>,
164+
Type<T7>,
165+
Type<T8>
166+
]
167+
): Type<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8>
168+
export function union(...types: Type<any>[]): Type<any> {
169+
return new UnionType(types)
170+
}

src/types/IntersectionType.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import Type from './Type'
22
import compareTypes from '../compareTypes'
3-
import invariant from '../invariant'
43

5-
import ObjectType, { Property } from './ObjectType'
4+
import { Property } from './ObjectType'
65
import ObjectTypeProperty from './ObjectTypeProperty'
76
import Validation, { ErrorTuple, IdentifierPath } from '../Validation'
87

9-
export default class IntersectionType<T extends {}> extends Type<T> {
8+
export default class IntersectionType<T> extends Type<T> {
109
typeName: string = 'IntersectionType'
11-
types: Type<T>[] = [];
10+
types: Type<any>[]
11+
12+
constructor(types: Type<any>[]) {
13+
super()
14+
this.types = types
15+
}
1216

1317
*errors(
1418
validation: Validation<any>,

src/types/TupleType.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import compareTypes from '../compareTypes'
33
import getErrorMessage from '../getErrorMessage'
44
import Validation, { ErrorTuple, IdentifierPath } from '../Validation'
55

6-
export default class TupleType<T> extends Type<T[]> {
6+
export default class TupleType<T extends []> extends Type<T> {
77
typeName: string = 'TupleType'
8-
types: Type<T>[]
8+
types: { [Index in keyof T]: Type<T[Index]> } & { length: T['length'] }
99

10-
constructor(types: Type<T>[] = []) {
10+
constructor(
11+
types: { [Index in keyof T]: Type<T[Index]> } & { length: T['length'] }
12+
) {
1113
super()
1214
this.types = types
1315
}
@@ -24,7 +26,11 @@ export default class TupleType<T> extends Type<T[]> {
2426
return
2527
}
2628
for (let i = 0; i < length; i++) {
27-
yield* types[i].errors(validation, path.concat(i), input[i])
29+
yield* (types[i] as Type<any>).errors(
30+
validation,
31+
path.concat(i),
32+
input[i]
33+
)
2834
}
2935
}
3036

@@ -36,7 +42,7 @@ export default class TupleType<T> extends Type<T[]> {
3642
return false
3743
}
3844
for (let i = 0; i < length; i++) {
39-
const type = types[i]
45+
const type = types[i] as Type<any>
4046
if (!type.accepts(input[i])) {
4147
return false
4248
}

src/types/UnionType.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import compareTypes from '../compareTypes'
66

77
export default class UnionType<T> extends Type<T> {
88
typeName: string = 'UnionType'
9-
types: Type<T>[]
9+
types: Type<any>[]
1010

11-
constructor(types: Type<T>[]) {
11+
constructor(types: Type<any>[]) {
1212
super()
1313
this.types = types
1414
}

0 commit comments

Comments
 (0)