typescript:S4138 should not apply to non-arrays

Sonar version: Version 9.3 (build 51899)

Rule typescript:S4138 suggests to refactor for(;;) loops into for ... of loops.

This makes sense if the iterated entity is an actual array, but not for array-like entities which do not support the for...of syntax.

Examples include NodeList and FileList, and in general entities respecting the ArrayLike<T> built-in TypeScript interface.

function processFiles(fileList: FileList) {
    for (let i = 0; i < fileList.length; i++) {
        const file = fileList[i];
        // process file
    }
}

This code can be rewritten by:

  • converting the object to an actual array with Array.from(fileList)
  • using Array.prototype.forEach.call(fileList, callback)

However these changes lead to (slightly?) worse performance and/or less clarity and just sidestep this false positive.

Hello,

Thanks for the feedback. Currently this rule is purely syntax-based, no type information is considered, thus those issues you are getting. I can still imagine that someone would like to refactor using for-of even for NodeList, making code more maintainable. Otherwise you can simply won’t fix the issue, it has minor severity.
In other words I am not sure we should exclude array-like structures from this rule.

Strictly speaking it is a false positive, but I agree it can simply be manually ignored.
Ultimately it is your call.