or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdasync.mdcollections.mdindex.mdnumbers.mdobjects.mdprimitives.mdstrings.mdtyped-arrays.mdvalidation.mdweb-apis.md

async.mddocs/

0

# Async and Promises

1

2

Type checking for promises, async functions, generators, and iterables including both synchronous and asynchronous variants.

3

4

## Capabilities

5

6

### Promise Type Checking

7

8

Check if a value is a promise-like object or native Promise.

9

10

```typescript { .api }

11

/**

12

* Check if value is promise-like (has .then() and .catch() methods)

13

* @param value - Value to check

14

* @returns True if value is promise-like

15

*/

16

function isPromise<T = unknown>(value: unknown): value is Promise<T>;

17

18

/**

19

* Check if value is a native Promise

20

* @param value - Value to check

21

* @returns True if value is native Promise

22

*/

23

function isNativePromise<T = unknown>(value: unknown): value is Promise<T>;

24

```

25

26

**Usage Examples:**

27

28

```typescript

29

import is from '@sindresorhus/is';

30

31

is.promise(Promise.resolve(42)); // => true

32

is.promise(new Promise(() => {})); // => true

33

34

// Promise-like objects

35

const thenable = {

36

then: (resolve: Function) => resolve(42),

37

catch: (reject: Function) => {}

38

};

39

is.promise(thenable); // => true

40

41

// Native Promise checking

42

is.nativePromise(Promise.resolve(42)); // => true

43

is.nativePromise(thenable); // => false

44

45

// Type guard usage

46

async function handlePromise(value: unknown) {

47

if (is.promise(value)) {

48

// value is now typed as Promise<unknown>

49

const result = await value;

50

console.log(result);

51

}

52

}

53

```

54

55

### Async Function Type Checking

56

57

Check if a value is an async function.

58

59

```typescript { .api }

60

/**

61

* Check if value is an async function

62

* @param value - Value to check

63

* @returns True if value is async function

64

*/

65

function isAsyncFunction<T = unknown>(value: unknown): value is ((...arguments_: any[]) => Promise<T>);

66

```

67

68

**Usage Examples:**

69

70

```typescript

71

import is from '@sindresorhus/is';

72

73

is.asyncFunction(async () => {}); // => true

74

is.asyncFunction(async function() {}); // => true

75

is.asyncFunction(() => {}); // => false

76

is.asyncFunction(function() {}); // => false

77

78

// Type guard usage

79

async function executeAsync(fn: unknown) {

80

if (is.asyncFunction(fn)) {

81

// fn is now typed as async function

82

const result = await fn();

83

console.log(result);

84

}

85

}

86

```

87

88

### Generator Type Checking

89

90

Check if a value is a generator object.

91

92

```typescript { .api }

93

/**

94

* Check if value is a generator

95

* @param value - Value to check

96

* @returns True if value is generator

97

*/

98

function isGenerator(value: unknown): value is Generator;

99

```

100

101

**Usage Examples:**

102

103

```typescript

104

import is from '@sindresorhus/is';

105

106

function* myGenerator() {

107

yield 1;

108

yield 2;

109

}

110

111

const gen = myGenerator();

112

is.generator(gen); // => true

113

is.generator(myGenerator); // => false (function, not generator instance)

114

115

// Type guard usage

116

function processGenerator(value: unknown) {

117

if (is.generator(value)) {

118

// value is now typed as Generator

119

const { value: firstValue, done } = value.next();

120

console.log(firstValue, done);

121

}

122

}

123

```

124

125

### Generator Function Type Checking

126

127

Check if a value is a generator function.

128

129

```typescript { .api }

130

/**

131

* Check if value is a generator function

132

* @param value - Value to check

133

* @returns True if value is generator function

134

*/

135

function isGeneratorFunction(value: unknown): value is GeneratorFunction;

136

```

137

138

**Usage Examples:**

139

140

```typescript

141

import is from '@sindresorhus/is';

142

143

function* myGenerator() {

144

yield 1;

145

}

146

147

is.generatorFunction(myGenerator); // => true

148

is.generatorFunction(myGenerator()); // => false (generator instance)

149

is.generatorFunction(() => {}); // => false

150

151

// Type guard usage

152

function createGenerator(fn: unknown) {

153

if (is.generatorFunction(fn)) {

154

// fn is now typed as GeneratorFunction

155

const generator = fn();

156

return generator;

157

}

158

}

159

```

160

161

### Async Generator Type Checking

162

163

Check if a value is an async generator object.

164

165

```typescript { .api }

166

/**

167

* Check if value is an async generator

168

* @param value - Value to check

169

* @returns True if value is async generator

170

*/

171

function isAsyncGenerator(value: unknown): value is AsyncGenerator;

172

```

173

174

**Usage Examples:**

175

176

```typescript

177

import is from '@sindresorhus/is';

178

179

async function* myAsyncGenerator() {

180

yield 1;

181

yield 2;

182

}

183

184

const asyncGen = myAsyncGenerator();

185

is.asyncGenerator(asyncGen); // => true

186

187

// Regular generator is not async generator

188

function* regularGen() { yield 1; }

189

is.asyncGenerator(regularGen()); // => false

190

191

// Type guard usage

192

async function processAsyncGenerator(value: unknown) {

193

if (is.asyncGenerator(value)) {

194

// value is now typed as AsyncGenerator

195

const { value: firstValue, done } = await value.next();

196

console.log(firstValue, done);

197

}

198

}

199

```

200

201

### Async Generator Function Type Checking

202

203

Check if a value is an async generator function.

204

205

```typescript { .api }

206

/**

207

* Check if value is an async generator function

208

* @param value - Value to check

209

* @returns True if value is async generator function

210

*/

211

function isAsyncGeneratorFunction(value: unknown): value is AsyncGeneratorFunction;

212

```

213

214

**Usage Examples:**

215

216

```typescript

217

import is from '@sindresorhus/is';

218

219

async function* myAsyncGenerator() {

220

yield 1;

221

}

222

223

is.asyncGeneratorFunction(myAsyncGenerator); // => true

224

is.asyncGeneratorFunction(myAsyncGenerator()); // => false (async generator instance)

225

226

function* regularGenerator() { yield 1; }

227

is.asyncGeneratorFunction(regularGenerator); // => false

228

229

// Type guard usage

230

function createAsyncGenerator(fn: unknown) {

231

if (is.asyncGeneratorFunction(fn)) {

232

// fn is now typed as AsyncGeneratorFunction

233

const asyncGenerator = fn();

234

return asyncGenerator;

235

}

236

}

237

```

238

239

### Iterable Type Checking

240

241

Check if a value is iterable (has Symbol.iterator).

242

243

```typescript { .api }

244

/**

245

* Check if value is iterable

246

* @param value - Value to check

247

* @returns True if value is iterable

248

*/

249

function isIterable<T = unknown>(value: unknown): value is Iterable<T>;

250

```

251

252

**Usage Examples:**

253

254

```typescript

255

import is from '@sindresorhus/is';

256

257

is.iterable([]); // => true

258

is.iterable('hello'); // => true

259

is.iterable(new Set()); // => true

260

is.iterable(new Map()); // => true

261

is.iterable({}); // => false

262

263

function* generator() { yield 1; }

264

is.iterable(generator()); // => true

265

266

// Type guard usage

267

function processIterable(value: unknown) {

268

if (is.iterable(value)) {

269

// value is now typed as Iterable<unknown>

270

for (const item of value) {

271

console.log(item);

272

}

273

}

274

}

275

```

276

277

### Async Iterable Type Checking

278

279

Check if a value is async iterable (has Symbol.asyncIterator).

280

281

```typescript { .api }

282

/**

283

* Check if value is async iterable

284

* @param value - Value to check

285

* @returns True if value is async iterable

286

*/

287

function isAsyncIterable<T = unknown>(value: unknown): value is AsyncIterable<T>;

288

```

289

290

**Usage Examples:**

291

292

```typescript

293

import is from '@sindresorhus/is';

294

295

async function* asyncGenerator() {

296

yield 1;

297

yield 2;

298

}

299

300

is.asyncIterable(asyncGenerator()); // => true

301

is.asyncIterable([]); // => false (regular arrays are not async iterable)

302

303

// Custom async iterable

304

const customAsyncIterable = {

305

async *[Symbol.asyncIterator]() {

306

yield 1;

307

yield 2;

308

}

309

};

310

is.asyncIterable(customAsyncIterable); // => true

311

312

// Type guard usage

313

async function processAsyncIterable(value: unknown) {

314

if (is.asyncIterable(value)) {

315

// value is now typed as AsyncIterable<unknown>

316

for await (const item of value) {

317

console.log(item);

318

}

319

}

320

}

321

```

322

323

### Observable Type Checking

324

325

Check if a value is an Observable-like object.

326

327

```typescript { .api }

328

/**

329

* Check if value is Observable-like

330

* @param value - Value to check

331

* @returns True if value is Observable-like

332

*/

333

function isObservable(value: unknown): value is ObservableLike;

334

335

type ObservableLike = {

336

subscribe(observer: (value: unknown) => void): void;

337

[Symbol.observable](): ObservableLike;

338

};

339

```

340

341

**Usage Examples:**

342

343

```typescript

344

import is from '@sindresorhus/is';

345

import { Observable } from 'rxjs';

346

347

const observable = new Observable(subscriber => {

348

subscriber.next(1);

349

subscriber.complete();

350

});

351

352

is.observable(observable); // => true

353

354

// Custom observable-like

355

const customObservable = {

356

subscribe: (observer: Function) => observer(42),

357

[Symbol.observable]: function() { return this; }

358

};

359

is.observable(customObservable); // => true

360

361

is.observable(Promise.resolve(42)); // => false

362

363

// Type guard usage

364

function processObservable(value: unknown) {

365

if (is.observable(value)) {

366

// value is now typed as ObservableLike

367

value.subscribe(result => console.log(result));

368

}

369

}

370

```

371

372

## Usage Patterns

373

374

### Promise Handling

375

376

```typescript

377

import is from '@sindresorhus/is';

378

379

async function handleAsyncValue(value: unknown) {

380

if (is.promise(value)) {

381

const result = await value;

382

console.log('Promise resolved:', result);

383

} else if (is.asyncFunction(value)) {

384

const result = await value();

385

console.log('Async function result:', result);

386

}

387

}

388

```

389

390

### Generator Processing

391

392

```typescript

393

import is from '@sindresorhus/is';

394

395

function processGeneratorValue(value: unknown) {

396

if (is.generator(value)) {

397

// Process regular generator

398

let result = value.next();

399

while (!result.done) {

400

console.log(result.value);

401

result = value.next();

402

}

403

} else if (is.asyncGenerator(value)) {

404

// Process async generator

405

processAsyncGenerator(value);

406

}

407

}

408

409

async function processAsyncGenerator(gen: AsyncGenerator) {

410

let result = await gen.next();

411

while (!result.done) {

412

console.log(result.value);

413

result = await gen.next();

414

}

415

}

416

```

417

418

## Notes

419

420

- `is.promise()` accepts both native Promises and thenable objects (with `.then()` and `.catch()`)

421

- Use `is.nativePromise()` when you specifically need native Promise instances

422

- Generators and generator functions are different - one creates the other

423

- Async generators require `for await...of` loops or manual `await gen.next()` calls

424

- Observable checking looks for Symbol.observable or @@observable properties

425

- All async type checks work with TypeScript type guards for compile-time type narrowing