File tree Expand file tree Collapse file tree 6 files changed +72
-1
lines changed Expand file tree Collapse file tree 6 files changed +72
-1
lines changed Original file line number Diff line number Diff line change @@ -42,6 +42,7 @@ The validation errors are detailed. Adapted from the brilliant work in `flow-run
42
42
- [ ` t.readonlyArray(t.number()) ` ] ( #treadonlyarraytnumber )
43
43
- [ ` t.object(properties) ` ] ( #tobjectproperties )
44
44
- [ ` t.object({ required?, optional?, exact? }) ` ] ( #tobject-required-optional-exact- )
45
+ - [ ` t.opaque<DateString>(() => t.string()) ` ] ( #topaquedatestring--tstring )
45
46
- [ ` t.readonly(objectType) ` ] ( #treadonlyobjecttype )
46
47
- [ ` t.merge(...objectTypes) ` ] ( #tmergeobjecttypes )
47
48
- [ ` t.mergeInexact(...objectTypes) ` ] ( #tmergeinexactobjecttypes )
@@ -386,9 +387,13 @@ PersonType.assert({ name: 1 }) // error
386
387
PersonType .assert ({ name: ' dude' , age: ' old' }) // error
387
388
```
388
389
390
+ ### ` t.opaque<DateString>(() => t.string()) `
391
+
392
+ A validator that requires the value to be a string, but presents the type as ` DateString ` (for instance with ` export opaque type DateString = string ` )
393
+
389
394
### ` t.readonly(objectType) `
390
395
391
- Use ` t.readOnly (t.object(...)) ` or ` t.readOnly (t.merge(...)) ` etc. Doesn't require the object to be frozen, just allows the extracted type to be readonly.
396
+ Use ` t.readonly (t.object(...)) ` or ` t.readonly (t.merge(...)) ` etc. Doesn't require the object to be frozen, just allows the extracted type to be readonly.
392
397
393
398
### ` t.merge(...objectTypes) `
394
399
Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ import NumberType from './types/NumberType'
14
14
import NumericLiteralType from './types/NumericLiteralType'
15
15
import ObjectType from './types/ObjectType'
16
16
import ObjectTypeProperty from './types/ObjectTypeProperty'
17
+ import OpaqueType from './types/OpaqueType'
17
18
import oneOf from './oneOf'
18
19
import PrimitiveLiteralType from './types/PrimitiveLiteralType'
19
20
import RecordType from './types/RecordType'
@@ -47,6 +48,7 @@ export {
47
48
NumericLiteralType,
48
49
ObjectType,
49
50
ObjectTypeProperty,
51
+ OpaqueType,
50
52
oneOf,
51
53
PrimitiveLiteralType,
52
54
RecordType,
@@ -68,6 +70,7 @@ export {
68
70
69
71
declare export function any(): Type<any>
70
72
declare export function unknown(): Type<mixed>
73
+ declare export function opaque<T>(type: () => Type<any>): OpaqueType<T>
71
74
72
75
declare export function array<T>(elementType: Type<T>): Type<T[]>
73
76
declare export function readonlyArray<T>(
Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ import NumberType from './types/NumberType'
12
12
import NumericLiteralType from './types/NumericLiteralType'
13
13
import ObjectType from './types/ObjectType'
14
14
import ObjectTypeProperty from './types/ObjectTypeProperty'
15
+ import OpaqueType from './types/OpaqueType'
15
16
import oneOf from './oneOf'
16
17
import PrimitiveLiteralType from './types/PrimitiveLiteralType'
17
18
import RecordType from './types/RecordType'
@@ -45,6 +46,7 @@ export {
45
46
NumericLiteralType ,
46
47
ObjectType ,
47
48
ObjectTypeProperty ,
49
+ OpaqueType ,
48
50
oneOf ,
49
51
PrimitiveLiteralType ,
50
52
RecordType ,
@@ -66,6 +68,8 @@ export {
66
68
67
69
export const any = ( ) : Type < any > => new AnyType ( )
68
70
export const unknown = ( ) : Type < unknown > => new UnknownType ( )
71
+ export const opaque = < T > ( type : ( ) => Type < any > ) : OpaqueType < T > =>
72
+ new OpaqueType < T > ( type )
69
73
70
74
export const array = < T > ( elementType : Type < T > ) : Type < T [ ] > =>
71
75
new ArrayType ( elementType )
Original file line number Diff line number Diff line change
1
+ // @flow
2
+
3
+ import Type from './Type'
4
+
5
+ declare class OpaqueType<T> extends Type<T> {
6
+ type: () => Type<any>;
7
+
8
+ constructor(type: () => Type<any>): void;
9
+ }
10
+
11
+ export default OpaqueType
Original file line number Diff line number Diff line change
1
+ import Type from './Type'
2
+ import Validation , { IdentifierPath } from '../Validation'
3
+ import RuntimeTypeErrorItem from '../errorReporting/RuntimeTypeErrorItem'
4
+
5
+ export default class TypeReference < T > extends Type < T > {
6
+ typeName = 'TypeReference'
7
+ readonly type : ( ) => Type < any >
8
+
9
+ constructor ( type : ( ) => Type < any > ) {
10
+ super ( )
11
+ this . type = type
12
+ }
13
+
14
+ resolveType ( ) : Type < any > {
15
+ return this . type ( ) . resolveType ( )
16
+ }
17
+
18
+ * errors (
19
+ validation : Validation ,
20
+ path : IdentifierPath ,
21
+ input : any
22
+ ) : Iterable < RuntimeTypeErrorItem > {
23
+ yield * this . type ( ) . errors ( validation , path , input )
24
+ }
25
+
26
+ accepts ( input : any ) : input is T {
27
+ return this . type ( ) . accepts ( input )
28
+ }
29
+
30
+ get acceptsSomeCompositeTypes ( ) : boolean {
31
+ return this . type ( ) . acceptsSomeCompositeTypes
32
+ }
33
+
34
+ toString ( ) : string {
35
+ return this . type ( ) . toString ( )
36
+ }
37
+ }
Original file line number Diff line number Diff line change
1
+ import * as t from '../src'
2
+ import { expect } from 'chai'
3
+
4
+ describe ( `t.opaque` , function ( ) {
5
+ const DateString : t . OpaqueType < any > = t . opaque ( ( ) => t . string ( ) )
6
+
7
+ it ( `works` , function ( ) {
8
+ DateString . assert ( 'foo' )
9
+ expect ( DateString . accepts ( 'foo' ) ) . to . be . true
10
+ } )
11
+ } )
You can’t perform that action at this time.
0 commit comments