or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

builtin-types.mdindex.mdproperty-types.mdsymbol-analysis.mdtype-analysis.mdtype-constraints.mdtype-predicates.mdtype-safety.mdtype-specifiers.md

builtin-types.mddocs/

0

# Builtin Type Checks

1

2

Specialized predicates for identifying built-in TypeScript types like Promise, Error, and readonly utility types. These functions help recognize common patterns and built-in type constructs in TypeScript code.

3

4

## Capabilities

5

6

### Promise Type Checks

7

8

Functions for identifying Promise-related types and patterns.

9

10

```typescript { .api }

11

/**

12

* Checks if a type is Promise-like (extends Promise)

13

* Example: class DerivedClass extends Promise<number> {} - DerivedClass is Promise-like

14

*/

15

function isPromiseLike(program: ts.Program, type: ts.Type): boolean;

16

17

/**

18

* Checks if a type is PromiseConstructor-like

19

* Example: const value = Promise; value.reject - value is PromiseConstructor-like

20

*/

21

function isPromiseConstructorLike(program: ts.Program, type: ts.Type): boolean;

22

```

23

24

**Usage Examples:**

25

26

```typescript

27

import { isPromiseLike, isPromiseConstructorLike } from "@typescript-eslint/type-utils";

28

29

// In an ESLint rule checking async patterns

30

export default {

31

create(context) {

32

const services = context.parserServices;

33

const program = services.program;

34

const checker = program.getTypeChecker();

35

36

return {

37

VariableDeclarator(node) {

38

if (node.init) {

39

const tsNode = services.esTreeNodeToTSNodeMap.get(node.init);

40

const type = checker.getTypeAtLocation(tsNode);

41

42

if (isPromiseLike(program, type)) {

43

// Handle Promise-like types

44

context.report({

45

node,

46

messageId: "promiseDetected",

47

data: { typeName: checker.typeToString(type) }

48

});

49

}

50

51

if (isPromiseConstructorLike(program, type)) {

52

// Handle Promise constructor references

53

context.report({

54

node,

55

messageId: "promiseConstructorUsage"

56

});

57

}

58

}

59

}

60

};

61

}

62

};

63

```

64

65

### Error Type Checks

66

67

Functions for identifying Error-related types and inheritance patterns.

68

69

```typescript { .api }

70

/**

71

* Checks if a type extends the Error class

72

* Example: class Foo extends Error {} - new Foo() is Error-like

73

*/

74

function isErrorLike(program: ts.Program, type: ts.Type): boolean;

75

76

/**

77

* Checks if a type is a readonly Error type (like Readonly<Error>)

78

*/

79

function isReadonlyErrorLike(program: ts.Program, type: ts.Type): boolean;

80

```

81

82

**Usage Examples:**

83

84

```typescript

85

import { isErrorLike, isReadonlyErrorLike } from "@typescript-eslint/type-utils";

86

87

// In an ESLint rule for error handling

88

export default {

89

create(context) {

90

const services = context.parserServices;

91

const program = services.program;

92

const checker = program.getTypeChecker();

93

94

return {

95

ThrowStatement(node) {

96

const tsNode = services.esTreeNodeToTSNodeMap.get(node.argument);

97

const type = checker.getTypeAtLocation(tsNode);

98

99

if (!isErrorLike(program, type)) {

100

context.report({

101

node: node.argument,

102

messageId: "throwNonError"

103

});

104

}

105

},

106

107

CatchClause(node) {

108

if (node.param) {

109

const tsNode = services.esTreeNodeToTSNodeMap.get(node.param);

110

const type = checker.getTypeAtLocation(tsNode);

111

112

if (isReadonlyErrorLike(program, type)) {

113

context.report({

114

node: node.param,

115

messageId: "readonlyErrorInCatch"

116

});

117

}

118

}

119

}

120

};

121

}

122

};

123

```

124

125

### Readonly Utility Type Checks

126

127

Functions for identifying TypeScript's built-in readonly utility types.

128

129

```typescript { .api }

130

/**

131

* Checks if a type is a Readonly type alias

132

* Example: type T = Readonly<{ foo: 'bar' }> - T is ReadonlyTypeLike

133

*/

134

function isReadonlyTypeLike(

135

program: ts.Program,

136

type: ts.Type,

137

predicate?: (subType: { aliasSymbol: ts.Symbol; aliasTypeArguments: readonly ts.Type[] } & ts.Type) => boolean

138

): boolean;

139

```

140

141

**Usage Examples:**

142

143

```typescript

144

import { isReadonlyTypeLike } from "@typescript-eslint/type-utils";

145

146

// Check for Readonly utility type usage

147

export default {

148

create(context) {

149

const services = context.parserServices;

150

const program = services.program;

151

const checker = program.getTypeChecker();

152

153

return {

154

TSTypeReference(node) {

155

const tsNode = services.esTreeNodeToTSNodeMap.get(node);

156

const type = checker.getTypeAtLocation(tsNode);

157

158

if (isReadonlyTypeLike(program, type)) {

159

// Found Readonly<T> usage

160

context.report({

161

node,

162

messageId: "readonlyUtilityType"

163

});

164

}

165

}

166

};

167

}

168

};

169

```

170

171

### Generic Builtin Type Checking

172

173

Generic functions for building custom builtin type checkers.

174

175

```typescript { .api }

176

/**

177

* Generic function to check if a type matches a built-in type alias with a predicate

178

*/

179

function isBuiltinTypeAliasLike(

180

program: ts.Program,

181

type: ts.Type,

182

predicate: (subType: {aliasSymbol: ts.Symbol; aliasTypeArguments: readonly ts.Type[]} & ts.Type) => boolean

183

): boolean;

184

185

/**

186

* Checks if a type is like a built-in symbol with the given name(s)

187

*/

188

function isBuiltinSymbolLike(

189

program: ts.Program,

190

type: ts.Type,

191

symbolName: string | string[]

192

): boolean;

193

194

/**

195

* Recursive helper function for built-in symbol-like checks.

196

* Handles inheritance, unions, intersections, and type parameters.

197

*/

198

function isBuiltinSymbolLikeRecurser(

199

program: ts.Program,

200

type: ts.Type,

201

predicate: (subType: ts.Type) => boolean | null

202

): boolean;

203

```

204

205

**Usage Examples:**

206

207

```typescript

208

import {

209

isBuiltinTypeAliasLike,

210

isBuiltinSymbolLike,

211

isBuiltinSymbolLikeRecurser

212

} from "@typescript-eslint/type-utils";

213

214

// Custom builtin type checker for Record<K, V>

215

function isRecordLike(program: ts.Program, type: ts.Type): boolean {

216

return isBuiltinTypeAliasLike(program, type, (subType) => {

217

return subType.aliasSymbol?.name === 'Record' &&

218

subType.aliasTypeArguments?.length === 2;

219

});

220

}

221

222

// Check for Map or Set types

223

function isMapOrSetLike(program: ts.Program, type: ts.Type): boolean {

224

return isBuiltinSymbolLike(program, type, ['Map', 'Set']);

225

}

226

227

// Custom predicate-based checker

228

function isIterableLike(program: ts.Program, type: ts.Type): boolean {

229

return isBuiltinSymbolLikeRecurser(program, type, (subType) => {

230

// Check if type has Symbol.iterator method

231

const checker = program.getTypeChecker();

232

const iteratorSymbol = checker.getPropertyOfType(subType, '__@iterator');

233

return iteratorSymbol ? true : null;

234

});

235

}

236

237

// Usage in ESLint rule

238

export default {

239

create(context) {

240

const services = context.parserServices;

241

const program = services.program;

242

const checker = program.getTypeChecker();

243

244

return {

245

VariableDeclarator(node) {

246

if (node.init) {

247

const tsNode = services.esTreeNodeToTSNodeMap.get(node.init);

248

const type = checker.getTypeAtLocation(tsNode);

249

250

if (isRecordLike(program, type)) {

251

// Handle Record types

252

}

253

254

if (isMapOrSetLike(program, type)) {

255

// Handle Map/Set types

256

}

257

258

if (isIterableLike(program, type)) {

259

// Handle iterable types

260

}

261

}

262

}

263

};

264

}

265

};

266

```

267

268

## Advanced Builtin Type Patterns

269

270

### Custom Type Family Checkers

271

272

```typescript

273

// Example: Creating a checker for all array-like builtin types

274

import { isBuiltinSymbolLikeRecurser } from "@typescript-eslint/type-utils";

275

276

function isArrayLikeBuiltin(program: ts.Program, type: ts.Type): boolean {

277

return isBuiltinSymbolLikeRecurser(program, type, (subType) => {

278

const checker = program.getTypeChecker();

279

const symbol = subType.symbol || subType.aliasSymbol;

280

281

if (!symbol) return null;

282

283

const arrayLikeNames = [

284

'Array', 'ReadonlyArray', 'Int8Array', 'Uint8Array',

285

'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array',

286

'Float32Array', 'Float64Array', 'ArrayBuffer'

287

];

288

289

return arrayLikeNames.includes(symbol.name) ? true : null;

290

});

291

}

292

```

293

294

### Promise Pattern Detection

295

296

```typescript

297

// Example: Comprehensive Promise pattern analysis

298

import { isPromiseLike, isPromiseConstructorLike } from "@typescript-eslint/type-utils";

299

300

function analyzePromisePatterns(

301

program: ts.Program,

302

type: ts.Type,

303

checker: ts.TypeChecker

304

): {

305

isPromise: boolean;

306

isConstructor: boolean;

307

isThenable: boolean;

308

} {

309

const isPromise = isPromiseLike(program, type);

310

const isConstructor = isPromiseConstructorLike(program, type);

311

312

// Check for thenable (has .then method)

313

const thenProperty = checker.getPropertyOfType(type, 'then');

314

const isThenable = !!thenProperty;

315

316

return { isPromise, isConstructor, isThenable };

317

}

318

```

319

320

### Error Hierarchy Analysis

321

322

```typescript

323

// Example: Analyzing error type hierarchies

324

import { isErrorLike, isReadonlyErrorLike } from "@typescript-eslint/type-utils";

325

326

function analyzeErrorHierarchy(

327

program: ts.Program,

328

type: ts.Type,

329

checker: ts.TypeChecker

330

): {

331

isError: boolean;

332

isReadonlyError: boolean;

333

errorName: string | null;

334

customError: boolean;

335

} {

336

const isError = isErrorLike(program, type);

337

const isReadonlyError = isReadonlyErrorLike(program, type);

338

339

let errorName: string | null = null;

340

let customError = false;

341

342

if (isError) {

343

const symbol = type.symbol || type.aliasSymbol;

344

errorName = symbol?.name || null;

345

346

// Check if it's a custom error (not built-in Error)

347

customError = errorName !== 'Error' && errorName !== null;

348

}

349

350

return { isError, isReadonlyError, errorName, customError };

351

}

352

```