0
# Comparison Classes
1
2
tcompare provides direct access to comparison classes for advanced usage scenarios. These classes offer performance benefits when making multiple comparisons and allow for custom comparison logic through inheritance.
3
4
## Class Hierarchy
5
6
```
7
Format
8
└── Same
9
├── Strict
10
├── Has
11
│ ├── HasStrict (uses Strict.prototype.test)
12
│ └── Match
13
│ └── MatchStrict (fails if a==b && a!==b)
14
├── MatchOnly (uses Match.prototype.test)
15
└── MatchOnlyStrict (uses MatchStrict.prototype.test)
16
```
17
18
## Capabilities
19
20
### Base Format Class
21
22
The foundational class for all formatting and comparison operations.
23
24
```typescript { .api }
25
/**
26
* Base formatting class for converting values to strings
27
*/
28
class Format {
29
constructor(obj: any, options?: FormatOptions);
30
31
/** Generate formatted string representation of the object */
32
print(): string;
33
34
/** Check if the object is an array-like structure */
35
isArray(): boolean;
36
37
/** Get object keys for plain objects */
38
getPojoKeys(obj: any): string[];
39
40
/** Get object entries for plain objects */
41
getPojoEntries(obj: any): Array<[string, any]>;
42
}
43
```
44
45
### Same Class
46
47
Base comparison class providing deep equivalence with loose matching.
48
49
```typescript { .api }
50
/**
51
* Base class for all comparison operations - deep equivalence with loose comparison
52
*/
53
class Same extends Format {
54
constructor(obj: any, options: SameOptions);
55
56
/** Boolean indicating whether objects match after calling print() */
57
match: boolean;
58
59
/** Perform the comparison test - returns boolean or 'COMPLEX' for nested comparison */
60
test(): boolean | 'COMPLEX';
61
62
/** Generate diff string and set match property */
63
print(): string;
64
}
65
66
/**
67
* Options for all comparison operations
68
*/
69
interface SameOptions extends FormatOptions {
70
/** The pattern to test against */
71
expect: any;
72
/** Parent comparison object for nested comparisons */
73
parent?: Same;
74
/** Key in parent object */
75
key?: any;
76
/** Key in expected pattern */
77
expectKey?: any;
78
/** Number of lines of context to show in diffs */
79
diffContext?: number;
80
}
81
```
82
83
**Usage Examples:**
84
85
```typescript
86
import { Same } from "tcompare";
87
88
// Direct class usage
89
const comparison = new Same([1, 2, 3], {
90
expect: ["1", "2", "3"],
91
style: "js"
92
});
93
94
const diff = comparison.print();
95
console.log(comparison.match); // true
96
console.log(diff); // Empty string when match is true
97
```
98
99
### Strict Class
100
101
Deep equality comparison without type coercion, extending Same.
102
103
```typescript { .api }
104
/**
105
* Deep equality comparison without type coercion
106
*/
107
class Strict extends Same {
108
constructor(obj: any, options: SameOptions);
109
110
/** Override test method to enforce strict equality */
111
test(): boolean | 'COMPLEX';
112
}
113
```
114
115
**Usage Examples:**
116
117
```typescript
118
import { Strict } from "tcompare";
119
120
const comparison = new Strict([1, 2, 3], {
121
expect: ["1", "2", "3"]
122
});
123
124
console.log(comparison.print());
125
console.log(comparison.match); // false - no type coercion
126
```
127
128
### Has Class
129
130
Subset matching - only tests properties present in the expected pattern.
131
132
```typescript { .api }
133
/**
134
* Subset matching - all pattern fields must exist in object with loose comparison
135
*/
136
class Has extends Same {
137
constructor(obj: any, options: SameOptions);
138
139
/** Override to only compare fields present in expected pattern */
140
getPojoEntries(obj: any): Array<[string, any]>;
141
142
/** Check if structure should be treated as array */
143
isArray(): boolean;
144
}
145
```
146
147
**Usage Examples:**
148
149
```typescript
150
import { Has } from "tcompare";
151
152
const comparison = new Has(
153
{ name: "Alice", age: 25, city: "NYC" },
154
{ expect: { name: "Alice", age: "25" } }
155
);
156
157
console.log(comparison.match); // true - extra 'city' field ignored
158
```
159
160
### HasStrict Class
161
162
Subset matching with strict comparison for primitives.
163
164
```typescript { .api }
165
/**
166
* Subset matching with strict comparison for primitives
167
*/
168
class HasStrict extends Has {
169
constructor(obj: any, options: SameOptions);
170
171
/** Use strict comparison for primitives, loose for objects */
172
test(): boolean | 'COMPLEX';
173
}
174
```
175
176
### Match Class
177
178
Most flexible matching strategy with pattern support.
179
180
```typescript { .api }
181
/**
182
* Flexible pattern matching with support for regex, constructors, and string patterns
183
*/
184
class Match extends Has {
185
constructor(obj: any, options: SameOptions);
186
187
/** Extended test method supporting multiple pattern types */
188
test(): boolean | 'COMPLEX';
189
}
190
```
191
192
**Usage Examples:**
193
194
```typescript
195
import { Match } from "tcompare";
196
197
// Pattern matching with regular expressions
198
const regexMatch = new Match("hello@example.com", {
199
expect: /@example\.com$/
200
});
201
202
// Constructor pattern matching
203
const typeMatch = new Match(42, {
204
expect: Number
205
});
206
207
// String substring matching
208
const stringMatch = new Match("hello world", {
209
expect: "world"
210
});
211
```
212
213
### MatchOnly Class
214
215
Pattern matching with strict object shape requirements.
216
217
```typescript { .api }
218
/**
219
* Uses Match test but requires exact object shape (no extra fields)
220
*/
221
class MatchOnly extends Same {
222
constructor(obj: any, options: SameOptions);
223
224
/** Use Match.prototype.test for comparison logic */
225
test(): boolean | 'COMPLEX';
226
}
227
```
228
229
### MatchStrict Class
230
231
Pattern matching without type coercion.
232
233
```typescript { .api }
234
/**
235
* Like Match but fails on loose equality without strict equality
236
*/
237
class MatchStrict extends Match {
238
constructor(obj: any, options: SameOptions);
239
240
/** Enhanced test that rejects loose-but-not-strict equality */
241
test(): boolean | 'COMPLEX';
242
}
243
```
244
245
### MatchOnlyStrict Class
246
247
Most restrictive matching - strict patterns with exact object shape.
248
249
```typescript { .api }
250
/**
251
* Uses MatchStrict test but requires exact object shape
252
*/
253
class MatchOnlyStrict extends Same {
254
constructor(obj: any, options: SameOptions);
255
256
/** Use MatchStrict.prototype.test for comparison logic */
257
test(): boolean | 'COMPLEX';
258
}
259
```
260
261
## Advanced Usage Patterns
262
263
### Performance Optimization
264
265
When making many comparisons with the same options, instantiate classes directly to avoid function call overhead:
266
267
```typescript
268
import { Same, SameOptions } from "tcompare";
269
270
const options: SameOptions = {
271
expect: { name: String, age: Number },
272
style: "js",
273
diffContext: 5
274
};
275
276
// Reuse options object for multiple comparisons
277
const users = [
278
{ name: "Alice", age: 25 },
279
{ name: "Bob", age: 30 },
280
{ name: "Charlie", age: "invalid" } // Will fail
281
];
282
283
users.forEach(user => {
284
const comparison = new Same(user, { ...options, expect: options.expect });
285
const diff = comparison.print();
286
287
if (!comparison.match) {
288
console.log(`Invalid user: ${diff}`);
289
}
290
});
291
```
292
293
### Custom Comparison Logic
294
295
Extend existing classes to implement custom comparison behavior:
296
297
```typescript
298
import { Match } from "tcompare";
299
300
class EmailMatch extends Match {
301
test(): boolean | 'COMPLEX' {
302
const obj = this.object;
303
const pattern = this.expect;
304
305
// Custom email validation logic
306
if (typeof pattern === 'string' && pattern === 'email') {
307
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
308
return typeof obj === 'string' && emailRegex.test(obj);
309
}
310
311
// Fall back to parent logic
312
return super.test();
313
}
314
}
315
316
// Usage
317
const emailComparison = new EmailMatch("user@example.com", {
318
expect: 'email'
319
});
320
321
console.log(emailComparison.match); // true for valid email
322
```
323
324
### Accessing Internal State
325
326
Classes expose internal properties for advanced inspection:
327
328
```typescript
329
import { Same } from "tcompare";
330
331
const comparison = new Same({ a: 1, b: 2 }, {
332
expect: { a: 1, b: 3 }
333
});
334
335
// Access internal object and expected pattern
336
console.log('Testing:', comparison.object);
337
console.log('Against:', comparison.expect);
338
339
// Generate diff and check match
340
const diff = comparison.print();
341
console.log('Match:', comparison.match);
342
console.log('Diff:', diff);
343
```