0
# PropTypes Validation
1
2
React PropTypes compatibility layer providing component prop validation interface. **Important**: This is a stub implementation - no actual validation is performed. All validator functions are no-op functions that return null.
3
4
## Capabilities
5
6
### PropTypes Object
7
8
Complete PropTypes API with all standard validators for React compatibility.
9
10
```typescript { .api }
11
/**
12
* PropTypes validation object providing React-compatible prop validation interface
13
* Note: This is a stub implementation - no actual validation is performed
14
*/
15
interface PropTypes {
16
/** No-op stub function - provides any type validation interface */
17
any: PropTypeStub;
18
19
/** No-op stub function - provides array validation interface */
20
array: PropTypeStub;
21
22
/** No-op stub function factory - provides array type validation interface */
23
arrayOf(type: any): PropTypeStub;
24
25
/** No-op stub function - provides boolean validation interface */
26
bool: PropTypeStub;
27
28
/** No-op stub function - provides element validation interface */
29
element: PropTypeStub;
30
31
/** No-op stub function - provides function validation interface */
32
func: PropTypeStub;
33
34
/** No-op stub function factory - provides instance validation interface */
35
instanceOf(expectedClass: any): PropTypeStub;
36
37
/** No-op stub function - provides node validation interface */
38
node: PropTypeStub;
39
40
/** No-op stub function - provides number validation interface */
41
number: PropTypeStub;
42
43
/** No-op stub function - provides object validation interface */
44
object: PropTypeStub;
45
46
/** No-op stub function factory - provides object type validation interface */
47
objectOf(type: any): PropTypeStub;
48
49
/** No-op stub function factory - provides enum validation interface */
50
oneOf(types: any[]): PropTypeStub;
51
52
/** No-op stub function factory - provides union type validation interface */
53
oneOfType(types: any[]): PropTypeStub;
54
55
/** No-op stub function factory - provides shape validation interface */
56
shape(shape: { [key: string]: any }): PropTypeStub;
57
58
/** No-op stub function - provides string validation interface */
59
string: PropTypeStub;
60
61
/** No-op stub function - provides symbol validation interface */
62
symbol: PropTypeStub;
63
64
/** No-op function for compatibility */
65
checkPropTypes(): null;
66
}
67
68
/**
69
* PropType stub function interface (no validation performed)
70
*/
71
interface PropTypeStub {
72
(): void;
73
isRequired: PropTypeStub;
74
}
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
import { PropTypes, Component } from "inferno-compat";
81
82
// Class component with PropTypes
83
class UserProfile extends Component {
84
static propTypes = {
85
name: PropTypes.string.isRequired,
86
age: PropTypes.number,
87
email: PropTypes.string.isRequired,
88
isActive: PropTypes.bool,
89
roles: PropTypes.arrayOf(PropTypes.string),
90
address: PropTypes.shape({
91
street: PropTypes.string,
92
city: PropTypes.string,
93
zipCode: PropTypes.string
94
}),
95
onUpdate: PropTypes.func,
96
avatar: PropTypes.element,
97
metadata: PropTypes.object,
98
id: PropTypes.oneOfType([
99
PropTypes.string,
100
PropTypes.number
101
]),
102
status: PropTypes.oneOf(['active', 'inactive', 'pending'])
103
};
104
105
static defaultProps = {
106
age: 0,
107
isActive: true,
108
roles: []
109
};
110
111
render() {
112
const { name, age, email, isActive } = this.props;
113
return (
114
<div className="user-profile">
115
<h2>{name}</h2>
116
<p>Age: {age}</p>
117
<p>Email: {email}</p>
118
<p>Status: {isActive ? 'Active' : 'Inactive'}</p>
119
</div>
120
);
121
}
122
}
123
124
// Function component with PropTypes
125
function ProductCard({ title, price, category, onAddToCart, image }) {
126
return (
127
<div className="product-card">
128
{image}
129
<h3>{title}</h3>
130
<p>Category: {category}</p>
131
<p>Price: ${price}</p>
132
<button onClick={onAddToCart}>Add to Cart</button>
133
</div>
134
);
135
}
136
137
ProductCard.propTypes = {
138
title: PropTypes.string.isRequired,
139
price: PropTypes.number.isRequired,
140
category: PropTypes.string,
141
onAddToCart: PropTypes.func.isRequired,
142
image: PropTypes.element
143
};
144
145
ProductCard.defaultProps = {
146
category: 'General'
147
};
148
```
149
150
### Validator Types
151
152
#### Basic Types
153
154
```typescript { .api }
155
// String validation
156
PropTypes.string // Validates string values
157
PropTypes.string.isRequired // Required string
158
159
// Number validation
160
PropTypes.number // Validates numeric values
161
PropTypes.number.isRequired // Required number
162
163
// Boolean validation
164
PropTypes.bool // Validates boolean values
165
PropTypes.bool.isRequired // Required boolean
166
167
// Function validation
168
PropTypes.func // Validates function values
169
PropTypes.func.isRequired // Required function
170
171
// Object validation
172
PropTypes.object // Validates object values
173
PropTypes.object.isRequired // Required object
174
175
// Array validation
176
PropTypes.array // Validates array values
177
PropTypes.array.isRequired // Required array
178
179
// Any type validation
180
PropTypes.any // Accepts any type
181
PropTypes.any.isRequired // Required (any type)
182
183
// Symbol validation
184
PropTypes.symbol // Validates symbol values
185
PropTypes.symbol.isRequired // Required symbol
186
```
187
188
#### Complex Types
189
190
```typescript { .api }
191
// Array of specific type
192
PropTypes.arrayOf(PropTypes.string) // Array of strings
193
PropTypes.arrayOf(PropTypes.number) // Array of numbers
194
PropTypes.arrayOf(PropTypes.object) // Array of objects
195
196
// Object with values of specific type
197
PropTypes.objectOf(PropTypes.string) // Object with string values
198
PropTypes.objectOf(PropTypes.number) // Object with number values
199
200
// One of specific values (enum)
201
PropTypes.oneOf(['red', 'green', 'blue']) // Color enum
202
PropTypes.oneOf([1, 2, 3]) // Number enum
203
PropTypes.oneOf(['small', 'medium', 'large']) // Size enum
204
205
// One of specific types (union)
206
PropTypes.oneOfType([
207
PropTypes.string,
208
PropTypes.number
209
]) // String or number
210
211
PropTypes.oneOfType([
212
PropTypes.arrayOf(PropTypes.string),
213
PropTypes.string
214
]) // String or array of strings
215
216
// Instance of specific class
217
class CustomClass {}
218
PropTypes.instanceOf(CustomClass) // Instance of CustomClass
219
PropTypes.instanceOf(Date) // Date instance
220
PropTypes.instanceOf(Error) // Error instance
221
222
// React elements and nodes
223
PropTypes.element // React element
224
PropTypes.node // Any renderable content (element, string, number, array)
225
226
// Object shape validation
227
PropTypes.shape({
228
id: PropTypes.number.isRequired,
229
name: PropTypes.string.isRequired,
230
email: PropTypes.string,
231
preferences: PropTypes.shape({
232
theme: PropTypes.oneOf(['light', 'dark']),
233
language: PropTypes.string
234
})
235
})
236
```
237
238
### Usage Patterns
239
240
#### Component Props Validation
241
242
```typescript
243
import { PropTypes, Component, createElement } from "inferno-compat";
244
245
// Modal component
246
class Modal extends Component {
247
static propTypes = {
248
isOpen: PropTypes.bool.isRequired,
249
title: PropTypes.string,
250
children: PropTypes.node,
251
onClose: PropTypes.func.isRequired,
252
size: PropTypes.oneOf(['small', 'medium', 'large']),
253
showCloseButton: PropTypes.bool,
254
closeOnOverlayClick: PropTypes.bool,
255
customStyles: PropTypes.object
256
};
257
258
static defaultProps = {
259
size: 'medium',
260
showCloseButton: true,
261
closeOnOverlayClick: true
262
};
263
264
render() {
265
if (!this.props.isOpen) return null;
266
267
return createElement('div', { className: 'modal-overlay' },
268
createElement('div', { className: `modal modal-${this.props.size}` },
269
this.props.title && createElement('h2', null, this.props.title),
270
createElement('div', { className: 'modal-content' }, this.props.children),
271
this.props.showCloseButton &&
272
createElement('button', { onClick: this.props.onClose }, 'Close')
273
)
274
);
275
}
276
}
277
278
// Form input component
279
function FormInput({
280
type,
281
name,
282
value,
283
placeholder,
284
onChange,
285
onBlur,
286
error,
287
disabled,
288
required
289
}) {
290
return createElement('div', { className: 'form-input' },
291
createElement('input', {
292
type,
293
name,
294
value,
295
placeholder,
296
onChange,
297
onBlur,
298
disabled,
299
required,
300
className: error ? 'error' : ''
301
}),
302
error && createElement('span', { className: 'error-message' }, error)
303
);
304
}
305
306
FormInput.propTypes = {
307
type: PropTypes.oneOf(['text', 'email', 'password', 'number', 'tel']),
308
name: PropTypes.string.isRequired,
309
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
310
placeholder: PropTypes.string,
311
onChange: PropTypes.func.isRequired,
312
onBlur: PropTypes.func,
313
error: PropTypes.string,
314
disabled: PropTypes.bool,
315
required: PropTypes.bool
316
};
317
318
FormInput.defaultProps = {
319
type: 'text',
320
disabled: false,
321
required: false
322
};
323
```
324
325
#### Higher-Order Component PropTypes
326
327
```typescript
328
import { PropTypes } from "inferno-compat";
329
330
// HOC with PropTypes validation
331
function withLoading(WrappedComponent) {
332
function WithLoadingComponent(props) {
333
if (props.isLoading) {
334
return createElement('div', { className: 'loading' }, 'Loading...');
335
}
336
337
return createElement(WrappedComponent, props);
338
}
339
340
WithLoadingComponent.propTypes = {
341
...WrappedComponent.propTypes,
342
isLoading: PropTypes.bool.isRequired
343
};
344
345
WithLoadingComponent.displayName =
346
`WithLoading(${WrappedComponent.displayName || WrappedComponent.name})`;
347
348
return WithLoadingComponent;
349
}
350
351
// Context provider component
352
function ThemeProvider({ theme, children }) {
353
// Theme provider logic here
354
return createElement('div', { className: `theme-${theme}` }, children);
355
}
356
357
ThemeProvider.propTypes = {
358
theme: PropTypes.oneOf(['light', 'dark', 'auto']).isRequired,
359
children: PropTypes.node.isRequired
360
};
361
```
362
363
### React Compatibility Notes
364
365
#### No Actual Validation
366
This PropTypes implementation is a compatibility layer that provides the same API as React's PropTypes but performs no actual validation. In a production environment, you might want to:
367
368
- Use a separate prop validation library for runtime checking
369
- Rely on TypeScript for compile-time type checking
370
- Implement custom validation logic if needed
371
372
#### Development vs Production
373
In React, PropTypes are typically stripped out in production builds. With inferno-compat:
374
375
- PropTypes declarations remain in the code
376
- No performance impact since validators are no-ops
377
- Maintains compatibility with existing React codebases
378
379
#### Migration from React
380
When migrating from React:
381
382
- Existing PropTypes declarations work without changes
383
- No runtime prop validation warnings
384
- Consider using TypeScript for type safety
385
- PropTypes serve as documentation for component APIs
386
387
### TypeScript Integration
388
389
For TypeScript projects, PropTypes can supplement interface definitions:
390
391
```typescript
392
interface UserProps {
393
name: string;
394
age?: number;
395
email: string;
396
isActive?: boolean;
397
}
398
399
class User extends Component<UserProps> {
400
static propTypes = {
401
name: PropTypes.string.isRequired,
402
age: PropTypes.number,
403
email: PropTypes.string.isRequired,
404
isActive: PropTypes.bool
405
};
406
407
render() {
408
// TypeScript provides compile-time type checking
409
// PropTypes provide runtime API documentation
410
return <div>{this.props.name}</div>;
411
}
412
}
413
```
414
415
### checkPropTypes Function
416
417
```typescript { .api }
418
/**
419
* No-op function for React compatibility
420
* In React, this manually runs prop type checking
421
* @returns null (no-op)
422
*/
423
checkPropTypes(): null;
424
```
425
426
This function exists for compatibility but performs no action in inferno-compat.