11import Type from './Type'
22
33import ObjectTypeProperty from './ObjectTypeProperty'
4- import ObjectTypeIndexer from './ObjectTypeIndexer'
5-
6- export type Property < K extends string | number | symbol , V > =
7- | ObjectTypeProperty < K , V >
8- | ObjectTypeIndexer < K , V >
94
105import getErrorMessage from '../getErrorMessage'
116import Validation , { ErrorTuple , IdentifierPath } from '../Validation'
@@ -23,17 +18,14 @@ import { keyToString } from '../errorReporting/typeOf'
2318export default class ObjectType < T extends { } > extends Type < T > {
2419 typeName = 'ObjectType'
2520 readonly properties : ObjectTypeProperty < keyof T , any > [ ]
26- readonly indexers : ObjectTypeIndexer < any , any > [ ]
2721 readonly exact : boolean
2822
2923 constructor (
3024 properties : ObjectTypeProperty < keyof T , any > [ ] = [ ] ,
31- indexers : ObjectTypeIndexer < any , any > [ ] = [ ] ,
3225 exact = true
3326 ) {
3427 super ( )
3528 this . properties = properties
36- this . indexers = indexers
3729 this . exact = exact
3830 properties . forEach ( prop => ( prop . __objectType = this ) )
3931 }
@@ -58,15 +50,7 @@ export default class ObjectType<T extends {}> extends Type<T> {
5850 }
5951 validation . startCycle ( this , input )
6052
61- if ( this . indexers . length > 0 ) {
62- if ( input instanceof Object && Array . isArray ( input ) ) {
63- yield [ path , getErrorMessage ( 'ERR_EXPECT_OBJECT' ) , this ]
64- return
65- }
66- yield * collectErrorsWithIndexers ( this , validation , path , input )
67- } else {
68- yield * collectErrorsWithoutIndexers ( this , validation , path , input )
69- }
53+ yield * collectErrorsWithoutIndexers ( this , validation , path , input )
7054 if ( this . exact ) {
7155 yield * collectErrorsExact ( this , validation , path , input )
7256 }
@@ -86,11 +70,7 @@ export default class ObjectType<T extends {}> extends Type<T> {
8670 startValidationCycle ( this , input )
8771
8872 let result
89- if ( this . indexers . length > 0 ) {
90- result = acceptsWithIndexers ( this , input )
91- } else {
92- result = acceptsWithoutIndexers ( this , input )
93- }
73+ result = acceptsWithoutIndexers ( this , input )
9474 if ( result && this . exact ) {
9575 result = acceptsExact ( this , input )
9676 }
@@ -99,7 +79,7 @@ export default class ObjectType<T extends {}> extends Type<T> {
9979 }
10080
10181 toString ( ) : string {
102- const { properties, indexers } = this
82+ const { properties } = this
10383 if ( inToStringCycle ( this ) ) {
10484 return '$Cycle<Record<string, any>>'
10585 }
@@ -108,45 +88,11 @@ export default class ObjectType<T extends {}> extends Type<T> {
10888 for ( let i = 0 ; i < properties . length ; i ++ ) {
10989 body . push ( properties [ i ] . toString ( ) )
11090 }
111- for ( let i = 0 ; i < indexers . length ; i ++ ) {
112- body . push ( indexers [ i ] . toString ( ) )
113- }
11491 endToStringCycle ( this )
11592 return `{\n${ indent ( body . join ( '\n' ) ) } \n}`
11693 }
11794}
11895
119- function acceptsWithIndexers (
120- type : ObjectType < any > ,
121- input : Record < string , any >
122- ) : boolean {
123- const { properties, indexers } = type
124- const seen = [ ]
125- for ( let i = 0 ; i < properties . length ; i ++ ) {
126- const property = properties [ i ]
127- if ( ! property . accepts ( input ) ) {
128- return false
129- }
130- seen . push ( property . key )
131- }
132- loop: for ( const key in input ) {
133- if ( seen . indexOf ( key ) !== - 1 ) {
134- continue
135- }
136- const value = ( input as any ) [ key ]
137- for ( let i = 0 ; i < indexers . length ; i ++ ) {
138- const indexer = indexers [ i ]
139- if ( indexer . acceptsKey ( key ) && indexer . acceptsValue ( value ) ) {
140- continue loop
141- }
142- }
143-
144- // if we got this far the key / value did not accepts any indexers.
145- return false
146- }
147- return true
148- }
149-
15096function acceptsWithoutIndexers (
15197 type : ObjectType < any > ,
15298 input : Record < string , any >
@@ -175,36 +121,6 @@ function acceptsExact(
175121 return true
176122}
177123
178- function * collectErrorsWithIndexers (
179- type : ObjectType < any > ,
180- validation : Validation < any > ,
181- path : IdentifierPath ,
182- input : Record < string , any >
183- ) : Generator < ErrorTuple , void , void > {
184- const { properties, indexers } = type
185- const seen = [ ]
186- for ( let i = 0 ; i < properties . length ; i ++ ) {
187- const property = properties [ i ]
188- yield * property . errors ( validation , path , input )
189- seen . push ( property . key )
190- }
191- loop: for ( const key in input ) {
192- if ( seen . indexOf ( key ) !== - 1 ) {
193- continue
194- }
195- const value = ( input as any ) [ key ]
196- for ( let i = 0 ; i < indexers . length ; i ++ ) {
197- const indexer = indexers [ i ]
198- if ( indexer . acceptsKey ( key ) && indexer . acceptsValue ( value ) ) {
199- continue loop
200- }
201- }
202-
203- // if we got this far the key / value was not accepted by any indexers.
204- yield [ path . concat ( key ) , getErrorMessage ( 'ERR_NO_INDEXER' ) , type ]
205- }
206- }
207-
208124function * collectErrorsWithoutIndexers (
209125 type : ObjectType < any > ,
210126 validation : Validation < any > ,
0 commit comments