or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundles-queries.mdcore-payload-types.mdindex.mdstorage-metadata.mdtype-guards.mdutility-types.mdvalidation-errors.md

type-guards.mddocs/

0

# Type Guards and Validation

1

2

Runtime validation functions for payload structure verification and type narrowing, including schema-specific type guards and comprehensive validation utilities for ensuring payload integrity.

3

4

## Capabilities

5

6

### Basic Payload Validation

7

8

Core functions for validating payload structure and type narrowing at runtime.

9

10

```typescript { .api }

11

/**

12

* Type guard to check if a value is any valid payload

13

* @param value - Value to check

14

* @returns True if value is a payload with schema property

15

*/

16

function isAnyPayload(value: unknown): value is Payload;

17

18

/**

19

* Type assertion factory for any payload

20

* @param value - Value to assert as payload

21

* @returns Value cast as Payload or throws error

22

*/

23

function asAnyPayload(value: unknown): Payload;

24

25

/**

26

* Higher-order function to create type guards for specific schemas

27

* @param schema - Array of schema strings to validate against

28

* @returns Type guard function for the specified schemas

29

*/

30

function isPayload<T extends Payload>(schema: string[]): (value: unknown) => value is T;

31

32

/**

33

* Higher-order function to create type assertion factories for specific schemas

34

* @param schema - Array of schema strings to validate against

35

* @returns Type assertion function for the specified schemas

36

*/

37

function asPayload<T extends Payload>(schema: string[]): (value: unknown) => T;

38

```

39

40

**Usage Examples:**

41

42

```typescript

43

import { isAnyPayload, asAnyPayload, isPayload } from "@xyo-network/payload-model";

44

45

// Check if value is any payload

46

const data: unknown = { schema: "network.example.test", message: "hello" };

47

48

if (isAnyPayload(data)) {

49

// TypeScript knows data is a Payload

50

console.log(data.schema);

51

}

52

53

// Create specific schema validators

54

const isUserPayload = isPayload<UserPayload>(["network.example.user"]);

55

const isProductPayload = isPayload<ProductPayload>(["network.example.product"]);

56

57

// Validate multiple schemas

58

const isValidPayload = isPayload([

59

"network.example.user",

60

"network.example.product",

61

"network.example.order"

62

]);

63

64

const unknownPayload: unknown = {

65

schema: "network.example.user",

66

name: "Alice",

67

email: "alice@example.com"

68

};

69

70

if (isUserPayload(unknownPayload)) {

71

// TypeScript knows this is UserPayload

72

console.log(unknownPayload.name);

73

}

74

75

// Type assertion

76

try {

77

const payload = asAnyPayload(data);

78

console.log("Valid payload:", payload.schema);

79

} catch (error) {

80

console.error("Invalid payload");

81

}

82

```

83

84

### Schema-Specific Type Guards

85

86

Advanced type guards for specific schema validation and type narrowing with enhanced type safety.

87

88

```typescript { .api }

89

/**

90

* Creates a type guard for a specific schema type

91

* @param schema - The schema string to validate against

92

* @returns Type guard function that narrows to the specific payload type

93

*/

94

function isPayloadOfSchemaType<T extends Payload | never = never>(

95

schema: T['schema']

96

): (x?: unknown | null) => x is T;

97

98

/**

99

* Creates a type guard for payloads with sources metadata

100

* @param schema - The schema string to validate against

101

* @returns Type guard function for payload with sources

102

*/

103

function isPayloadOfSchemaTypeWithSources<T extends Payload | never = never>(

104

schema: T['schema']

105

): (x?: unknown | null) => x is WithSources<T>;

106

107

/**

108

* Creates a negated type guard (returns true if NOT the specified schema)

109

* @param schema - The schema string to validate against

110

* @returns Type guard function that returns true if payload is NOT the specified schema

111

*/

112

function notPayloadOfSchemaType<T extends Payload | never = never>(

113

schema: T['schema']

114

): (x?: unknown | null) => x is T;

115

```

116

117

**Usage Examples:**

118

119

```typescript

120

import {

121

isPayloadOfSchemaType,

122

isPayloadOfSchemaTypeWithSources,

123

notPayloadOfSchemaType

124

} from "@xyo-network/payload-model";

125

126

// Define specific payload types

127

const UserSchema = "network.example.user" as const;

128

const ProductSchema = "network.example.product" as const;

129

130

interface UserPayload extends Payload {

131

schema: typeof UserSchema;

132

name: string;

133

email: string;

134

}

135

136

interface ProductPayload extends Payload {

137

schema: typeof ProductSchema;

138

name: string;

139

price: number;

140

}

141

142

// Create schema-specific type guards

143

const isUserPayload = isPayloadOfSchemaType<UserPayload>(UserSchema);

144

const isProductPayload = isPayloadOfSchemaType<ProductPayload>(ProductSchema);

145

const isUserWithSources = isPayloadOfSchemaTypeWithSources<UserPayload>(UserSchema);

146

147

// Usage in filtering

148

const payloads: Payload[] = [

149

{ schema: UserSchema, name: "Alice", email: "alice@example.com" },

150

{ schema: ProductSchema, name: "Laptop", price: 999 },

151

{ schema: UserSchema, name: "Bob", email: "bob@example.com" }

152

];

153

154

// Filter to specific payload types

155

const userPayloads = payloads.filter(isUserPayload);

156

const productPayloads = payloads.filter(isProductPayload);

157

158

// Type narrowing in conditionals

159

const unknownPayload: unknown = {

160

schema: UserSchema,

161

name: "Charlie",

162

email: "charlie@example.com"

163

};

164

165

if (isUserPayload(unknownPayload)) {

166

// TypeScript knows this is UserPayload

167

console.log(`User: ${unknownPayload.name} (${unknownPayload.email})`);

168

}

169

170

// Check for payloads with sources

171

const payloadWithSources: unknown = {

172

schema: UserSchema,

173

name: "David",

174

email: "david@example.com",

175

$sources: ["0x123..."]

176

};

177

178

if (isUserWithSources(payloadWithSources)) {

179

// TypeScript knows this has $sources array

180

console.log(`User with ${payloadWithSources.$sources.length} sources`);

181

}

182

183

// Negated validation

184

const nonUserPayloads = payloads.filter(notPayloadOfSchemaType(UserSchema));

185

```

186

187

### Schema Validation

188

189

Direct schema validation functions for string-based schema checking.

190

191

```typescript { .api }

192

/**

193

* Type guard to validate schema string format

194

* @param value - Value to check as schema

195

* @returns True if value matches schema regex pattern

196

*/

197

function isSchema(value: unknown): value is Schema;

198

199

/**

200

* Type assertion for schema strings

201

* @param value - Value to assert as schema

202

* @returns Value cast as Schema or throws error

203

*/

204

function asSchema(value: unknown): Schema;

205

```

206

207

**Usage Examples:**

208

209

```typescript

210

import { isSchema, asSchema } from "@xyo-network/payload-model";

211

212

// Validate schema format

213

const possibleSchema = "network.example.test";

214

215

if (isSchema(possibleSchema)) {

216

// TypeScript knows this is a valid Schema

217

console.log("Valid schema:", possibleSchema);

218

}

219

220

// Schema format validation

221

const schemas = [

222

"network.xyo.payload", // Valid

223

"network.example.user", // Valid

224

"invalid.schema.format.123", // May be invalid depending on regex

225

"network..empty.segment", // Invalid

226

"UPPERCASE.SCHEMA" // Invalid (must be lowercase)

227

];

228

229

const validSchemas = schemas.filter(isSchema);

230

console.log("Valid schemas:", validSchemas);

231

232

// Type assertion

233

try {

234

const schema = asSchema("network.example.valid");

235

console.log("Schema:", schema);

236

} catch (error) {

237

console.error("Invalid schema format");

238

}

239

240

// Dynamic schema validation

241

function createPayload(schemaStr: string, data: any) {

242

if (isSchema(schemaStr)) {

243

return {

244

schema: schemaStr,

245

...data

246

};

247

}

248

throw new Error("Invalid schema format");

249

}

250

```

251

252

### Validation Utilities

253

254

Additional validation utilities for working with payload collections and advanced validation scenarios.

255

256

```typescript { .api }

257

/**

258

* Type assertion factory that creates validation functions

259

*/

260

const AsObjectFactory: {

261

create<T>(guard: (value: unknown) => value is T): (value: unknown) => T;

262

createOptional<T>(guard: (value: unknown) => value is T): (value: unknown) => T | undefined;

263

};

264

```

265

266

**Usage Examples:**

267

268

```typescript

269

import { AsObjectFactory, isPayloadOfSchemaType } from "@xyo-network/payload-model";

270

271

// Create custom assertion functions

272

const UserSchema = "network.example.user" as const;

273

interface UserPayload extends Payload {

274

schema: typeof UserSchema;

275

name: string;

276

email: string;

277

}

278

279

const isUserPayload = isPayloadOfSchemaType<UserPayload>(UserSchema);

280

const asUserPayload = AsObjectFactory.create(isUserPayload);

281

const asOptionalUserPayload = AsObjectFactory.createOptional(isUserPayload);

282

283

// Use assertions

284

const data: unknown = {

285

schema: UserSchema,

286

name: "Alice",

287

email: "alice@example.com"

288

};

289

290

try {

291

const userPayload = asUserPayload(data);

292

console.log("User:", userPayload.name);

293

} catch (error) {

294

console.error("Not a valid user payload");

295

}

296

297

// Optional assertion (returns undefined instead of throwing)

298

const optionalUser = asOptionalUserPayload(data);

299

if (optionalUser) {

300

console.log("Optional user:", optionalUser.name);

301

}

302

303

// Process arrays with validation

304

const payloadData: unknown[] = [

305

{ schema: UserSchema, name: "Alice", email: "alice@example.com" },

306

{ schema: "network.example.product", name: "Laptop", price: 999 },

307

{ invalid: "data" }

308

];

309

310

const validUsers = payloadData

311

.map(asOptionalUserPayload)

312

.filter((user): user is UserPayload => user !== undefined);

313

314

console.log("Valid users:", validUsers.length);

315

```

316

317

## Advanced Usage Patterns

318

319

### Payload Type Discrimination

320

321

```typescript

322

import {

323

isPayloadOfSchemaType,

324

Payload

325

} from "@xyo-network/payload-model";

326

327

// Define multiple payload types

328

const UserSchema = "network.example.user" as const;

329

const ProductSchema = "network.example.product" as const;

330

const OrderSchema = "network.example.order" as const;

331

332

interface UserPayload extends Payload {

333

schema: typeof UserSchema;

334

name: string;

335

email: string;

336

}

337

338

interface ProductPayload extends Payload {

339

schema: typeof ProductSchema;

340

name: string;

341

price: number;

342

}

343

344

interface OrderPayload extends Payload {

345

schema: typeof OrderSchema;

346

userId: string;

347

productIds: string[];

348

total: number;

349

}

350

351

// Create discriminated union

352

type AppPayload = UserPayload | ProductPayload | OrderPayload;

353

354

// Create type guards

355

const isUserPayload = isPayloadOfSchemaType<UserPayload>(UserSchema);

356

const isProductPayload = isPayloadOfSchemaType<ProductPayload>(ProductSchema);

357

const isOrderPayload = isPayloadOfSchemaType<OrderPayload>(OrderSchema);

358

359

// Process different payload types

360

function processPayload(payload: AppPayload) {

361

if (isUserPayload(payload)) {

362

return `User: ${payload.name}`;

363

} else if (isProductPayload(payload)) {

364

return `Product: ${payload.name} - $${payload.price}`;

365

} else if (isOrderPayload(payload)) {

366

return `Order: ${payload.productIds.length} items - $${payload.total}`;

367

}

368

369

// TypeScript ensures exhaustive checking

370

const _exhaustiveCheck: never = payload;

371

return _exhaustiveCheck;

372

}

373

```

374

375

## Types Reference

376

377

### Type Guard Functions

378

379

- **`isAnyPayload(value)`**: Check if value is any payload

380

- **`isPayload<T>(schemas)`**: Create schema-specific type guard

381

- **`isPayloadOfSchemaType<T>(schema)`**: Create single schema type guard

382

- **`isPayloadOfSchemaTypeWithSources<T>(schema)`**: Type guard with sources validation

383

- **`notPayloadOfSchemaType<T>(schema)`**: Negated schema type guard

384

- **`isSchema(value)`**: Validate schema string format

385

386

### Assertion Functions

387

388

- **`asAnyPayload(value)`**: Assert value as any payload

389

- **`asPayload<T>(schemas)`**: Create schema-specific assertion

390

- **`asSchema(value)`**: Assert value as schema string

391

392

### Utility Functions

393

394

- **`AsObjectFactory.create<T>(guard)`**: Create assertion function from type guard

395

- **`AsObjectFactory.createOptional<T>(guard)`**: Create optional assertion function