or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-nodes.mddocument-processing.mderror-handling.mdindex.mdparse-stringify.mdparser-infrastructure.mdschema-configuration.mdtree-traversal.mdtype-guards.mdutilities.md

type-guards.mddocs/

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

```