0
# Type Guards
1
2
Runtime type checking functions for identifying different node types in the YAML AST. These functions provide type safety when working with nodes and enable proper handling of different node types in traversal and manipulation operations.
3
4
## Capabilities
5
6
### Node Type Identification
7
8
Type guard functions that narrow TypeScript types and enable safe node manipulation.
9
10
```typescript { .api }
11
/**
12
* Check if value is a Document
13
* @param node - Value to check
14
* @returns Type predicate for Document
15
*/
16
function isDocument(node: unknown): node is Document;
17
18
/**
19
* Check if value is any Node type
20
* @param value - Value to check
21
* @returns Type predicate for Node
22
*/
23
function isNode(value: unknown): value is Node;
24
25
/**
26
* Check if node is a Scalar
27
* @param node - Node to check
28
* @returns Type predicate for Scalar
29
*/
30
function isScalar(node: unknown): node is Scalar;
31
32
/**
33
* Check if node is a YAMLMap
34
* @param node - Node to check
35
* @returns Type predicate for YAMLMap
36
*/
37
function isMap(node: unknown): node is YAMLMap;
38
39
/**
40
* Check if node is a YAMLSeq
41
* @param node - Node to check
42
* @returns Type predicate for YAMLSeq
43
*/
44
function isSeq(node: unknown): node is YAMLSeq;
45
46
/**
47
* Check if node is a Pair
48
* @param node - Node to check
49
* @returns Type predicate for Pair
50
*/
51
function isPair(node: unknown): node is Pair;
52
53
/**
54
* Check if node is an Alias
55
* @param node - Node to check
56
* @returns Type predicate for Alias
57
*/
58
function isAlias(node: unknown): node is Alias;
59
60
/**
61
* Check if node is a Collection (YAMLMap or YAMLSeq)
62
* @param node - Node to check
63
* @returns Type predicate for Collection
64
*/
65
function isCollection(node: unknown): node is YAMLMap | YAMLSeq;
66
67
/**
68
* Check if node has an anchor
69
* @param node - Node to check
70
* @returns True if node has anchor property
71
*/
72
function hasAnchor(node: Node): boolean;
73
```
74
75
**Usage Examples:**
76
77
```typescript
78
import {
79
parseDocument,
80
isScalar,
81
isMap,
82
isSeq,
83
isAlias,
84
isCollection,
85
isPair
86
} from "yaml";
87
88
const doc = parseDocument(`
89
name: John Doe
90
age: 30
91
hobbies:
92
- reading
93
- coding
94
address:
95
city: New York
96
country: USA
97
alias_example: &shared_value "shared text"
98
alias_reference: *shared_value
99
`);
100
101
// Type-safe node processing
102
function processNode(node: unknown) {
103
if (isScalar(node)) {
104
console.log('Scalar value:', node.value);
105
console.log('Scalar type:', node.type);
106
107
// Safe to access scalar-specific properties
108
if (typeof node.value === 'string') {
109
console.log('String length:', node.value.length);
110
}
111
}
112
113
else if (isMap(node)) {
114
console.log('Map with', node.items.length, 'pairs');
115
116
// Safe to iterate over map items
117
node.items.forEach((pair, index) => {
118
if (isPair(pair)) {
119
console.log(`Pair ${index}:`, pair.key, '->', pair.value);
120
}
121
});
122
}
123
124
else if (isSeq(node)) {
125
console.log('Sequence with', node.items.length, 'items');
126
127
// Safe to iterate over sequence items
128
node.items.forEach((item, index) => {
129
console.log(`Item ${index}:`, item);
130
});
131
}
132
133
else if (isAlias(node)) {
134
console.log('Alias referencing:', node.source);
135
136
// Safe to resolve alias
137
const resolved = node.resolve(doc);
138
console.log('Resolved value:', resolved);
139
}
140
141
// Generic collection handling
142
if (isCollection(node)) {
143
console.log('Collection type:', isMap(node) ? 'Map' : 'Sequence');
144
console.log('Flow style:', node.flow);
145
console.log('Item count:', node.items.length);
146
}
147
}
148
149
// Process document contents
150
if (doc.contents) {
151
processNode(doc.contents);
152
}
153
```
154
155
### Advanced Type Checking
156
157
```typescript
158
import { parseDocument, isDocument, isNode, hasAnchor } from "yaml";
159
160
// Document type checking
161
const doc = parseDocument('key: value');
162
if (isDocument(doc)) {
163
// TypeScript knows this is a Document
164
console.log('Document errors:', doc.errors.length);
165
console.log('Document warnings:', doc.warnings.length);
166
}
167
168
// Node type checking with tree traversal
169
function traverseNodes(node: unknown) {
170
if (!isNode(node)) {
171
console.log('Not a node:', typeof node);
172
return;
173
}
174
175
// TypeScript knows this is a Node type
176
console.log('Node range:', node.range);
177
console.log('Node comment:', node.comment);
178
console.log('Has anchor:', hasAnchor(node));
179
180
if (hasAnchor(node)) {
181
console.log('Anchor name:', node.anchor);
182
}
183
184
// Recursively process collections
185
if (isCollection(node)) {
186
node.items.forEach(item => traverseNodes(item));
187
}
188
}
189
190
// Safe document content access
191
if (doc.contents && isNode(doc.contents)) {
192
traverseNodes(doc.contents);
193
}
194
```
195
196
### Conditional Processing
197
198
```typescript
199
import { parseDocument, isScalar, isMap, isSeq } from "yaml";
200
201
const doc = parseDocument(`
202
config:
203
name: "MyApp"
204
version: 1.0
205
features:
206
- auth
207
- logging
208
database:
209
host: localhost
210
port: 5432
211
`);
212
213
// Conditional processing based on node type
214
function extractStrings(node: unknown): string[] {
215
const strings: string[] = [];
216
217
if (isScalar(node)) {
218
if (typeof node.value === 'string') {
219
strings.push(node.value);
220
}
221
}
222
223
else if (isMap(node)) {
224
node.items.forEach(pair => {
225
if (isPair(pair)) {
226
strings.push(...extractStrings(pair.key));
227
strings.push(...extractStrings(pair.value));
228
}
229
});
230
}
231
232
else if (isSeq(node)) {
233
node.items.forEach(item => {
234
strings.push(...extractStrings(item));
235
});
236
}
237
238
return strings;
239
}
240
241
// Extract all strings from document
242
const allStrings = extractStrings(doc.contents);
243
console.log('All strings:', allStrings);
244
```
245
246
### Working with Mixed Collections
247
248
```typescript
249
import {
250
parseDocument,
251
isScalar,
252
isMap,
253
isSeq,
254
isPair,
255
YAMLMap,
256
YAMLSeq
257
} from "yaml";
258
259
// Function to safely add items to collections
260
function addToCollection(collection: unknown, key: any, value: any) {
261
if (isMap(collection)) {
262
// Safe map operations
263
collection.set(key, value);
264
console.log('Added to map:', key, '->', value);
265
}
266
267
else if (isSeq(collection)) {
268
// Safe sequence operations (ignore key for sequences)
269
collection.add(value);
270
console.log('Added to sequence:', value);
271
}
272
273
else {
274
console.log('Not a collection, cannot add items');
275
}
276
}
277
278
// Function to get collection size
279
function getCollectionSize(node: unknown): number {
280
if (isCollection(node)) {
281
return node.items.length;
282
}
283
return 0;
284
}
285
286
// Usage example
287
const doc = parseDocument('items: []');
288
const itemsNode = doc.get(['items'], true);
289
290
if (itemsNode) {
291
console.log('Initial size:', getCollectionSize(itemsNode));
292
addToCollection(itemsNode, null, 'first item');
293
addToCollection(itemsNode, null, 'second item');
294
console.log('Final size:', getCollectionSize(itemsNode));
295
}
296
```
297
298
## Type Identity Symbols
299
300
The library uses internal symbols for type identification, which are also exported for advanced use cases.
301
302
```typescript { .api }
303
/** Symbol used to identify Alias nodes */
304
declare const ALIAS: unique symbol;
305
306
/** Symbol used to identify Document nodes */
307
declare const DOC: unique symbol;
308
309
/** Symbol used to identify YAMLMap nodes */
310
declare const MAP: unique symbol;
311
312
/** Symbol used to identify Pair nodes */
313
declare const PAIR: unique symbol;
314
315
/** Symbol used to identify Scalar nodes */
316
declare const SCALAR: unique symbol;
317
318
/** Symbol used to identify YAMLSeq nodes */
319
declare const SEQ: unique symbol;
320
321
/** Symbol property used for node type identification */
322
declare const NODE_TYPE: unique symbol;
323
```
324
325
These symbols are used internally by the type guard functions but can also be accessed directly for advanced type checking scenarios.
326
327
## Type Definitions
328
329
```typescript { .api }
330
type Node = Alias | Scalar | YAMLMap | YAMLSeq;
331
type ParsedNode = Alias | Scalar<any> | YAMLMap<any, any> | YAMLSeq<any>;
332
type Collection = YAMLMap | YAMLSeq;
333
334
// Type guard function signatures
335
type TypeGuard<T> = (value: unknown) => value is T;
336
```