Transform ID:Documentation Index
Fetch the complete documentation index at: https://docs.refactron.dev/llms.txt
Use this file to discover all available pages before exploring further.
indexof_to_includes
Language: TypeScript
What it does
Rewrites theindexOf “contains” idiom built on Array.prototype.indexOf / String.prototype.indexOf to the boolean .includes(...) form added in ES2016. Five comparison shapes qualify:
| Before | After |
|---|---|
arr.indexOf(x) !== -1 | arr.includes(x) |
arr.indexOf(x) >= 0 | arr.includes(x) |
arr.indexOf(x) > -1 | arr.includes(x) |
arr.indexOf(x) === -1 | !arr.includes(x) |
arr.indexOf(x) < 0 | !arr.includes(x) |
-1 !== arr.indexOf(x), 0 <= arr.indexOf(x), etc.) are also handled. Position comparisons like arr.indexOf(x) > 5 or === 3 are NOT rewritten — .includes returns a boolean and the position information would be lost. Receiver-type checking goes through ts-morph’s type system. Transform at src/transform/transforms/typescript/indexof-to-includes.ts.
Detector pattern
The detector atsrc/analyze/detectors/typescript/indexof-comparison.ts walks ts-morph BinaryExpression nodes whose operator is one of the five recognised shapes and where exactly one side is an indexOf call expression with exactly one argument.
Preconditions
non_es2016— refuses when the resolved tsconfigtargetpredates ES2016.Array.prototype.includesandString.prototype.includesare ES2016 additions; rewriting on an older target would introduce a runtimeTypeErroron legacy platforms.non_callable_indexof— refuses when theindexOfreceiver’s ts-morph type is neither string nor array (nor ReadonlyArray). DOMNodeList, jQuery objects,Buffer, and custom classes haveindexOfmethods but no guaranteed.includes— and where they do, signatures may differ.- The comparison shape is exactly one of the five recognised contains / not-contains idioms above. Position comparisons (
> 5,=== 3) are silently ignored. - Exactly one side of the binary expression is an
indexOfcall —a.indexOf(x) !== b.indexOf(y)does not qualify.
Before / after
Edge cases NOT handled (skip via precondition)
- Position comparisons (
arr.indexOf(x) > 5,=== 3, etc.) —.includesreturns a boolean and discards position. - Non-string / non-array receivers (
Buffer,NodeList, jQuery, custom classes) —non_callable_indexof..includesis not guaranteed. - tsconfig
target< ES2016 —non_es2016;.includesdoesn’t exist on those engines. - Symmetric two-sided forms (
a.indexOf(x) !== b.indexOf(y)) — not a contains idiom.
Type safety here comes from ts-morph’s
getType() checks on the indexOf receiver. A union type like string | string[] is accepted only when every constituent is safe; anything else (object | string) refuses cleanly.