or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-tuple-types.mdbasic-types.mdchange-case-types.mddeep-wrapper-types.mdfunction-types.mdindex.mdkey-types.mdmark-wrapper-types.mdtype-checkers.mdutility-functions.mdutility-types.md

utility-functions.mddocs/

0

# Utility Functions

1

2

Runtime functions that complement the type system, providing assertions, factories, and helper utilities. These are actual JavaScript functions that work at runtime alongside the TypeScript type system.

3

4

## Capabilities

5

6

### assert

7

8

Runtime function that helps assert `condition`. When `condition` is falsy, it throws an error with `Assertion Error: ${message}`.

9

10

```typescript { .api }

11

function assert(condition: any, message?: string): asserts condition;

12

```

13

14

**Usage Example:**

15

16

```typescript

17

import { assert } from "ts-essentials";

18

19

function processUser(user: unknown) {

20

assert(user && typeof user === "object", "User must be an object");

21

assert("id" in user, "User must have an id");

22

assert("name" in user, "User must have a name");

23

24

// TypeScript now knows user is an object with id and name properties

25

console.log(user.id, user.name); // Type-safe access

26

}

27

28

// Usage in validation

29

function divide(a: number, b: number): number {

30

assert(b !== 0, "Division by zero is not allowed");

31

return a / b; // Safe to divide since b is not 0

32

}

33

34

// Custom assertion messages

35

function validateConfig(config: any) {

36

assert(config, "Configuration is required");

37

assert(config.apiKey, "API key is missing from configuration");

38

assert(typeof config.timeout === "number", "Timeout must be a number");

39

}

40

```

41

42

### UnreachableCaseError

43

44

Runtime class instance type that helps check exhaustiveness for `value`. When `value` isn't `never`, it shows TypeScript error.

45

46

```typescript { .api }

47

class UnreachableCaseError extends Error {

48

constructor(value: never);

49

}

50

```

51

52

**Usage Example:**

53

54

```typescript

55

import { UnreachableCaseError } from "ts-essentials";

56

57

type Status = "loading" | "success" | "error";

58

59

function handleStatus(status: Status): string {

60

switch (status) {

61

case "loading":

62

return "Loading...";

63

case "success":

64

return "Success!";

65

case "error":

66

return "Error occurred";

67

default:

68

// This ensures exhaustive checking

69

throw new UnreachableCaseError(status);

70

}

71

}

72

73

// If you add a new status type, TypeScript will error at the UnreachableCaseError line

74

type ExtendedStatus = "loading" | "success" | "error" | "pending";

75

76

function handleExtendedStatus(status: ExtendedStatus): string {

77

switch (status) {

78

case "loading":

79

return "Loading...";

80

case "success":

81

return "Success!";

82

case "error":

83

return "Error occurred";

84

// Missing "pending" case

85

default:

86

// TypeScript error: Argument of type 'string' is not assignable to parameter of type 'never'

87

throw new UnreachableCaseError(status);

88

}

89

}

90

```

91

92

### createFactoryWithConstraint

93

94

Runtime function that validates that type of `value` matches `Constraint` without changing resulting type of `value`. This is a ponyfill for TypeScript's `satisfies` operator.

95

96

```typescript { .api }

97

function createFactoryWithConstraint<Constraint>(): <T extends Constraint>(value: T) => T;

98

```

99

100

**Usage Example:**

101

102

```typescript

103

import { createFactoryWithConstraint } from "ts-essentials";

104

105

// Define a constraint interface

106

interface ApiEndpoint {

107

path: string;

108

method: "GET" | "POST" | "PUT" | "DELETE";

109

handler: (req: any) => any;

110

}

111

112

// Create a factory that ensures objects satisfy the constraint

113

const createEndpoint = createFactoryWithConstraint<ApiEndpoint>();

114

115

// Usage - type is preserved while ensuring constraint satisfaction

116

const userEndpoint = createEndpoint({

117

path: "/users",

118

method: "GET",

119

handler: (req) => ({ users: [] }),

120

// Can include additional properties not in constraint

121

middleware: ["auth", "logging"]

122

});

123

124

// userEndpoint has the exact type including the middleware property

125

// But TypeScript ensures it satisfies the ApiEndpoint constraint

126

127

// Error example - missing required properties

128

// const invalidEndpoint = createEndpoint({

129

// path: "/invalid"

130

// // Error: Property 'method' is missing

131

// });

132

133

// Configuration validation example

134

interface DatabaseConfig {

135

host: string;

136

port: number;

137

database: string;

138

}

139

140

const createDbConfig = createFactoryWithConstraint<DatabaseConfig>();

141

142

const prodConfig = createDbConfig({

143

host: "prod-db.example.com",

144

port: 5432,

145

database: "myapp",

146

// Additional properties are preserved

147

ssl: true,

148

maxConnections: 100

149

});

150

```

151

152

### isExact

153

154

Runtime function that validates that type of `actual` equals to `Expected`. Otherwise shows TypeScript error.

155

156

```typescript { .api }

157

function isExact<Expected>(): <T>(actual: T) => T extends Expected

158

? Expected extends T

159

? T

160

: never

161

: never;

162

```

163

164

**Usage Example:**

165

166

```typescript

167

import { isExact } from "ts-essentials";

168

169

// Create exact type checker

170

const checkExactUser = isExact<{ id: number; name: string }>();

171

172

// Valid - exact match

173

const validUser = checkExactUser({ id: 1, name: "Alice" });

174

175

// Invalid - missing property (TypeScript error)

176

// const invalidUser1 = checkExactUser({ id: 1 }); // Error

177

178

// Invalid - extra property (TypeScript error)

179

// const invalidUser2 = checkExactUser({ id: 1, name: "Alice", email: "alice@example.com" }); // Error

180

181

// Usage in testing

182

function testExactType<T>(value: T, expected: T): void {

183

const checker = isExact<T>();

184

checker(value); // Ensures exact type match

185

}

186

187

// Configuration validation

188

interface AppConfig {

189

apiUrl: string;

190

timeout: number;

191

retries: number;

192

}

193

194

const validateExactConfig = isExact<AppConfig>();

195

196

function loadConfig(config: unknown): AppConfig {

197

// This ensures config matches AppConfig exactly

198

return validateExactConfig(config as AppConfig);

199

}

200

```

201

202

### noop

203

204

Runtime function that does nothing with arguments `_args`. Useful for default callbacks and placeholders.

205

206

```typescript { .api }

207

function noop(..._args: any[]): void;

208

```

209

210

**Usage Example:**

211

212

```typescript

213

import { noop } from "ts-essentials";

214

215

// Default callback parameter

216

interface Options {

217

onSuccess?: (data: any) => void;

218

onError?: (error: Error) => void;

219

}

220

221

function processData(data: any, options: Options = {}) {

222

const { onSuccess = noop, onError = noop } = options;

223

224

try {

225

const result = transformData(data);

226

onSuccess(result);

227

} catch (error) {

228

onError(error as Error);

229

}

230

}

231

232

// Event handler placeholder

233

class EventEmitter {

234

private handlers: Map<string, Function> = new Map();

235

236

on(event: string, handler: Function = noop) {

237

this.handlers.set(event, handler);

238

}

239

240

emit(event: string, ...args: any[]) {

241

const handler = this.handlers.get(event) || noop;

242

handler(...args);

243

}

244

}

245

246

// Development vs production logging

247

const logger = process.env.NODE_ENV === "production"

248

? { log: noop, error: noop, warn: noop }

249

: console;

250

251

logger.log("This only logs in development");

252

253

// Conditional operations

254

function setupFeature(enabled: boolean, callback: () => void = noop) {

255

if (enabled) {

256

callback();

257

}

258

}

259

260

setupFeature(false); // No error, noop is used as default

261

```

262

263

## Advanced Usage

264

265

Combine utility functions for robust error handling and type safety:

266

267

```typescript

268

import { assert, UnreachableCaseError, createFactoryWithConstraint, isExact, noop } from "ts-essentials";

269

270

// Comprehensive validation pipeline

271

interface UserData {

272

id: number;

273

email: string;

274

role: "admin" | "user" | "guest";

275

}

276

277

const createUser = createFactoryWithConstraint<UserData>();

278

const validateExactUser = isExact<UserData>();

279

280

function processUserData(data: unknown): UserData {

281

// Runtime assertion

282

assert(data && typeof data === "object", "Data must be an object");

283

assert("id" in data && typeof data.id === "number", "Invalid user ID");

284

assert("email" in data && typeof data.email === "string", "Invalid email");

285

assert("role" in data, "Role is required");

286

287

// Exact type validation

288

const validatedData = validateExactUser(data as UserData);

289

290

// Constraint satisfaction

291

return createUser(validatedData);

292

}

293

294

// Exhaustive pattern matching with error handling

295

function getUserPermissions(role: UserData["role"]): string[] {

296

switch (role) {

297

case "admin":

298

return ["read", "write", "delete", "manage"];

299

case "user":

300

return ["read", "write"];

301

case "guest":

302

return ["read"];

303

default:

304

throw new UnreachableCaseError(role);

305

}

306

}

307

308

// Safe callback execution

309

function executeCallback<T extends any[]>(

310

callback: ((...args: T) => void) | undefined,

311

...args: T

312

): void {

313

const safeCallback = callback || noop;

314

try {

315

safeCallback(...args);

316

} catch (error) {

317

console.error("Callback execution failed:", error);

318

}

319

}

320

321

// Type-safe factory with validation

322

function createValidatedFactory<T>(

323

validator: (value: unknown) => value is T

324

) {

325

const factory = createFactoryWithConstraint<T>();

326

327

return function(value: unknown): T {

328

assert(validator(value), "Validation failed");

329

return factory(value as T);

330

};

331

}

332

```