or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-traversal.mdcode-analysis.mdcontrol-flow.mdindex.mdnode-typeguards.mdtext-processing.mdtype-guards.mdtype-utilities.mdvariable-usage.md

text-processing.mddocs/

0

# Text Processing and Validation

1

2

Text processing utilities for source code analysis including line range calculation, identifier validation, comment extraction, position-based operations, and various text validation functions for TypeScript constructs.

3

4

## Capabilities

5

6

### Line Range Analysis

7

8

Utilities for analyzing line structure and line breaks in source files.

9

10

```typescript { .api }

11

/**

12

* Get line ranges for all lines in a source file

13

* @param sourceFile - Source file to analyze

14

* @returns Array of line ranges with position and content length information

15

*/

16

function getLineRanges(sourceFile: ts.SourceFile): LineRange[];

17

18

/**

19

* Get the line break style used in a source file

20

* @param sourceFile - Source file to analyze

21

* @returns Line break string (e.g., '\n', '\r\n', '\r')

22

*/

23

function getLineBreakStyle(sourceFile: ts.SourceFile): string;

24

25

/**

26

* Check if two positions are on the same line

27

* @param sourceFile - Source file containing the positions

28

* @param pos1 - First position

29

* @param pos2 - Second position

30

* @returns true if both positions are on the same line

31

*/

32

function isSameLine(sourceFile: ts.SourceFile, pos1: number, pos2: number): boolean;

33

34

/**

35

* Line range interface with content length information

36

*/

37

interface LineRange extends ts.TextRange {

38

/** Length of actual content on the line (excluding line break) */

39

contentLength: number;

40

}

41

```

42

43

### Identifier and Name Validation

44

45

Utilities for validating TypeScript identifiers and property names.

46

47

```typescript { .api }

48

/**

49

* Check if text is a valid TypeScript identifier

50

* @param text - Text to validate

51

* @param languageVersion - TypeScript language version (optional)

52

* @returns true if text is valid identifier

53

*/

54

function isValidIdentifier(text: string, languageVersion?: ts.ScriptTarget): boolean;

55

56

/**

57

* Check if text can be used as property access (obj.prop)

58

* @param text - Text to validate

59

* @param languageVersion - TypeScript language version (optional)

60

* @returns true if text is valid for property access

61

*/

62

function isValidPropertyAccess(text: string, languageVersion?: ts.ScriptTarget): boolean;

63

64

/**

65

* Check if text is a valid property name

66

* @param text - Text to validate

67

* @param languageVersion - TypeScript language version (optional)

68

* @returns true if text is valid property name

69

*/

70

function isValidPropertyName(text: string, languageVersion?: ts.ScriptTarget): boolean;

71

72

/**

73

* Check if text is a valid numeric literal

74

* @param text - Text to validate

75

* @param languageVersion - TypeScript language version (optional)

76

* @returns true if text is valid numeric literal

77

*/

78

function isValidNumericLiteral(text: string, languageVersion?: ts.ScriptTarget): boolean;

79

80

/**

81

* Check if text is a valid JSX identifier

82

* @param text - Text to validate

83

* @param languageVersion - TypeScript language version (optional)

84

* @returns true if text is valid JSX identifier

85

*/

86

function isValidJsxIdentifier(text: string, languageVersion?: ts.ScriptTarget): boolean;

87

```

88

89

### Property Name Analysis

90

91

Utilities for working with property names and numeric properties.

92

93

```typescript { .api }

94

/**

95

* Extract property name from a property name node

96

* @param propertyName - Property name node

97

* @returns String representation of property name or undefined if not extractable

98

*/

99

function getPropertyName(propertyName: ts.PropertyName): string | undefined;

100

101

/**

102

* Check if property name is numeric

103

* @param name - Property name to check

104

* @returns true if name represents a numeric property

105

*/

106

function isNumericPropertyName(name: string | ts.__String): boolean;

107

```

108

109

### Well-Known Symbol Analysis

110

111

Utilities for analyzing well-known symbol property access.

112

113

```typescript { .api }

114

/**

115

* Check if expression is a well-known symbol literal (Symbol.iterator, etc.)

116

* @param node - Expression to check

117

* @returns true if expression is well-known symbol access

118

*/

119

function isWellKnownSymbolLiterally(node: ts.Expression): node is WellKnownSymbolLiteral;

120

121

/**

122

* Get property name information for well-known symbol

123

* @param node - Well-known symbol literal node

124

* @returns Property name information

125

* @deprecated Use getLateBoundPropertyNames instead

126

*/

127

function getPropertyNameOfWellKnownSymbol(node: WellKnownSymbolLiteral): PropertyName;

128

129

/**

130

* Interface for well-known symbol literal expressions

131

*/

132

interface WellKnownSymbolLiteral extends ts.PropertyAccessExpression {

133

expression: ts.Identifier & {text: 'Symbol', escapedText: 'symbol'};

134

}

135

136

/**

137

* Property name information

138

*/

139

interface PropertyName {

140

displayName: string;

141

symbolName: ts.__String;

142

}

143

```

144

145

### Late-Bound Property Analysis

146

147

Utilities for analyzing dynamically computed property names.

148

149

```typescript { .api }

150

/**

151

* Analyze late-bound property names from an expression

152

* @param node - Expression to analyze

153

* @param checker - Type checker instance

154

* @returns Late-bound property names information

155

*/

156

function getLateBoundPropertyNames(node: ts.Expression, checker: ts.TypeChecker): LateBoundPropertyNames;

157

158

/**

159

* Get late-bound property names from a property name node

160

* @param node - Property name node

161

* @param checker - Type checker instance

162

* @returns Late-bound property names information

163

*/

164

function getLateBoundPropertyNamesOfPropertyName(node: ts.PropertyName, checker: ts.TypeChecker): LateBoundPropertyNames;

165

166

/**

167

* Get single late-bound property name if deterministic

168

* @param node - Property name node

169

* @param checker - Type checker instance

170

* @returns Single property name if deterministic, undefined otherwise

171

*/

172

function getSingleLateBoundPropertyNameOfPropertyName(node: ts.PropertyName, checker: ts.TypeChecker): PropertyName | undefined;

173

174

/**

175

* Late-bound property names result

176

*/

177

interface LateBoundPropertyNames {

178

/** Whether all property names are known at compile time */

179

known: boolean;

180

/** Array of resolved property names */

181

names: PropertyName[];

182

}

183

```

184

185

### Expression Analysis

186

187

Utilities for analyzing expressions and their side effects.

188

189

```typescript { .api }

190

/**

191

* Check if expression has side effects

192

* @param node - Expression to analyze

193

* @param options - Side effect analysis options

194

* @returns true if expression may have side effects

195

*/

196

function hasSideEffects(node: ts.Expression, options?: SideEffectOptions): boolean;

197

198

/**

199

* Check if expression value is used (not discarded)

200

* @param node - Expression to check

201

* @returns true if expression value is used

202

*/

203

function isExpressionValueUsed(node: ts.Expression): boolean;

204

205

/**

206

* Get access kind for a node (read, write, delete)

207

* @param node - Node to analyze

208

* @returns Access kind flags

209

*/

210

function getAccessKind(node: ts.Node): AccessKind;

211

212

/**

213

* Check if expression is a reassignment target

214

* @param node - Expression to check

215

* @returns true if expression is being reassigned

216

*/

217

function isReassignmentTarget(node: ts.Expression): boolean;

218

219

/**

220

* Side effect analysis options

221

*/

222

enum SideEffectOptions {

223

None = 0,

224

TaggedTemplate = 1,

225

Constructor = 2,

226

JsxElement = 4

227

}

228

229

/**

230

* Access kind enumeration

231

*/

232

enum AccessKind {

233

None = 0,

234

Read = 1,

235

Write = 2,

236

Delete = 4,

237

ReadWrite = Read | Write,

238

Modification = Write | Delete

239

}

240

```

241

242

### Const Assertion Analysis

243

244

Utilities for analyzing const assertions and readonly contexts.

245

246

```typescript { .api }

247

/**

248

* Check if assertion expression is a const assertion

249

* @param node - Assertion expression to check

250

* @returns true if assertion is 'as const'

251

*/

252

function isConstAssertion(node: ts.AssertionExpression): boolean;

253

254

/**

255

* Check if expression is in const context

256

* @param node - Expression to check

257

* @returns true if expression is in const assertion context

258

*/

259

function isInConstContext(node: ts.Expression): boolean;

260

261

/**

262

* Check if call expression is readonly assignment declaration

263

* @param node - Call expression to check

264

* @param checker - Type checker instance

265

* @returns true if call creates readonly assignment

266

*/

267

function isReadonlyAssignmentDeclaration(node: ts.CallExpression, checker: ts.TypeChecker): boolean;

268

269

/**

270

* Check if call expression is bindable Object.defineProperty call

271

* @param node - Call expression to check

272

* @returns true if call is bindable defineProperty

273

*/

274

function isBindableObjectDefinePropertyCall(node: ts.CallExpression): boolean;

275

```

276

277

### Utility Functions

278

279

Miscellaneous text processing and utility functions.

280

281

```typescript { .api }

282

/**

283

* Remove parentheses from expression

284

* @param node - Expression that may be parenthesized

285

* @returns Unwrapped expression

286

*/

287

function unwrapParentheses(node: ts.Expression): ts.Expression;

288

289

/**

290

* Format pseudo big int value as string

291

* @param v - Pseudo big int value

292

* @returns Formatted string representation

293

*/

294

function formatPseudoBigInt(v: ts.PseudoBigInt): string;

295

296

/**

297

* Check if switch statement has exhaustive case clauses

298

* @param node - Switch statement to check

299

* @param checker - Type checker instance

300

* @returns true if all cases are covered

301

*/

302

function hasExhaustiveCaseClauses(node: ts.SwitchStatement, checker: ts.TypeChecker): boolean;

303

304

/**

305

* Get base class expression from class-like declaration

306

* @param node - Class-like declaration

307

* @returns Base class expression if present

308

*/

309

function getBaseOfClassLikeExpression(node: ts.ClassLikeDeclaration): ts.ExpressionWithTypeArguments | undefined;

310

```

311

312

### Directive Analysis

313

314

Utilities for analyzing TypeScript compiler directives.

315

316

```typescript { .api }

317

/**

318

* Get TypeScript check directive from source text

319

* @param source - Source text to analyze

320

* @returns Check directive if found

321

*/

322

function getTsCheckDirective(source: string): ts.CheckJsDirective | undefined;

323

324

/**

325

* Get check JS directive from source text (deprecated)

326

* @param source - Source text to analyze

327

* @returns Check directive if found

328

* @deprecated Use getTsCheckDirective instead

329

*/

330

function getCheckJsDirective(source: string): ts.CheckJsDirective | undefined;

331

```

332

333

**Usage Examples:**

334

335

```typescript

336

import * as ts from "typescript";

337

import {

338

getLineRanges,

339

isValidIdentifier,

340

getPropertyName,

341

hasSideEffects,

342

isConstAssertion,

343

unwrapParentheses,

344

SideEffectOptions,

345

AccessKind

346

} from "tsutils/util";

347

348

// Line analysis example

349

function analyzeSourceLines(sourceFile: ts.SourceFile) {

350

const lines = getLineRanges(sourceFile);

351

const lineBreakStyle = getLineBreakStyle(sourceFile);

352

353

console.log(`File has ${lines.length} lines`);

354

console.log(`Line break style: ${JSON.stringify(lineBreakStyle)}`);

355

356

lines.forEach((line, index) => {

357

console.log(`Line ${index + 1}: ${line.contentLength} characters`);

358

});

359

}

360

361

// Identifier validation example

362

function validateIdentifiers(identifiers: string[]) {

363

identifiers.forEach(id => {

364

if (isValidIdentifier(id)) {

365

console.log(`"${id}" is a valid identifier`);

366

} else {

367

console.log(`"${id}" is not a valid identifier`);

368

}

369

370

if (isValidPropertyAccess(id)) {

371

console.log(`"${id}" can be used in property access`);

372

}

373

});

374

}

375

376

// Property name analysis

377

function analyzePropertyAccess(node: ts.PropertyAccessExpression) {

378

const propertyName = getPropertyName(node.name);

379

if (propertyName) {

380

console.log(`Property name: ${propertyName}`);

381

382

if (isNumericPropertyName(propertyName)) {

383

console.log("Property name is numeric");

384

}

385

}

386

}

387

388

// Side effect analysis

389

function analyzeSideEffects(expression: ts.Expression) {

390

const hasEffects = hasSideEffects(expression, SideEffectOptions.None);

391

const hasEffectsWithConstructors = hasSideEffects(expression, SideEffectOptions.Constructor);

392

393

console.log(`Expression has side effects: ${hasEffects}`);

394

console.log(`With constructor calls: ${hasEffectsWithConstructors}`);

395

396

const isUsed = isExpressionValueUsed(expression);

397

console.log(`Expression value is used: ${isUsed}`);

398

}

399

400

// Const assertion analysis

401

function analyzeConstAssertions(node: ts.Node) {

402

if (ts.isAsExpression(node) || ts.isTypeAssertion(node)) {

403

if (isConstAssertion(node)) {

404

console.log("Found const assertion");

405

}

406

}

407

408

if (ts.isExpression(node) && isInConstContext(node)) {

409

console.log("Expression is in const context");

410

}

411

}

412

413

// Expression unwrapping

414

function analyzeExpression(expr: ts.Expression) {

415

const unwrapped = unwrapParentheses(expr);

416

417

if (unwrapped !== expr) {

418

console.log("Expression was parenthesized");

419

}

420

421

console.log(`Unwrapped expression: ${ts.SyntaxKind[unwrapped.kind]}`);

422

}

423

424

// Position-based analysis

425

function checkPositionInLine(sourceFile: ts.SourceFile, pos1: number, pos2: number) {

426

if (isSameLine(sourceFile, pos1, pos2)) {

427

console.log("Positions are on the same line");

428

} else {

429

console.log("Positions are on different lines");

430

}

431

}

432

```