@@ -33,11 +33,18 @@ class Collection extends BaseCollection
3333 private int $ perPage ;
3434
3535 /**
36- * The type of item in the collection.
36+ * The type of each items in the collection.
3737 *
3838 * @var string
3939 */
40- protected string $ typeOf = 'mixed ' ;
40+ protected string $ valueType = 'mixed ' ;
41+
42+ /**
43+ * The type of each keys in the collection.
44+ *
45+ * @var string
46+ */
47+ protected string $ keyType = 'mixed ' ;
4148
4249 /**
4350 * Collection constructor.
@@ -85,24 +92,53 @@ protected function invariantAmountOfItemsMustBeLessOrEqualsThanTotalItems(): boo
8592 * @return bool
8693 * @throws InvariantViolation
8794 */
88- protected function invariantItemsMustBeOfSameType (): bool
95+ protected function invariantItemsMustMatchTheRequiredType (): bool
8996 {
90- $ primitives = [ ' integer ' , ' boolean ' , ' float ' , ' string ' , ' array ' , ' object ' , ' callable ' ];
91- if ( $ this -> typeOf !== ' mixed ' ) {
92- $ check = in_array ($ this ->typeOf , $ primitives )
93- ? fn ($ value ): bool => gettype ($ value ) !== $ this ->typeOf
94- : fn ($ value ): bool => !($ value instanceof $ this ->typeOf );
97+ if ( $ this -> valueType !== ' mixed ' ) {
98+ $ primitives = [ ' integer ' , ' boolean ' , ' float ' , ' string ' , ' array ' , ' object ' , ' callable ' ];
99+ $ check = in_array ($ this ->valueType , $ primitives )
100+ ? fn ($ value ): bool => gettype ($ value ) !== $ this ->valueType
101+ : fn ($ value ): bool => !($ value instanceof $ this ->valueType );
95102
96103 foreach ($ this ->items as $ index => $ item ) {
97104 if ($ check ($ item )) {
98- throw new InvariantViolation ("All items must be type of {$ this ->typeOf }" );
105+ throw new InvariantViolation ("All items must be type of {$ this ->valueType }" );
99106 }
100107 }
101108 }
102109
103110 return true ;
104111 }
105112
113+ /**
114+ * Invariant: Check the collection keys to match the required type.
115+ *
116+ * Supported types:
117+ * - string
118+ * - integer
119+ *
120+ * @return bool
121+ * @throws InvariantViolation
122+ */
123+ protected function invariantKeysMustMatchTheRequiredType (): bool
124+ {
125+ if ($ this ->keyType !== 'mixed ' ) {
126+ $ supported = ['string ' , 'integer ' ];
127+ if (!in_array ($ this ->keyType , $ supported )) {
128+ throw new InvariantViolation (
129+ "Unsupported key type, must be one of " .implode (', ' , $ supported )
130+ );
131+ }
132+
133+ foreach ($ this ->items as $ index => $ item ) {
134+ if (gettype ($ index ) !== $ this ->keyType ) {
135+ throw new InvariantViolation ("All keys must be type of {$ this ->keyType }" );
136+ }
137+ }
138+ }
139+ return true ;
140+ }
141+
106142 /**
107143 * Return the total amount of items on the data source.
108144 *
0 commit comments