Flux.ai was started around 3 years ago in TypeScript with the default compiler settings. If we could go back in time, there is one setting we would surely change: noUncheckedIndexedAccess. By default, this setting is false. Many people believe it should be true.
What does noUncheckedIndexedAccess do? By default, TypeScript assumes any array element or object property you access dynamically actually exists:
In the example above, the function will throw an error if the string is empty, because str[0] returns undefined and doesn't have a toUpperCase function. TypeScript doesn't warn you about that, regardless of whether strict mode is enabled or not. This is a huge hole in type safety.
The flag noUncheckedIndexedAccess will plug that hole and force you to deal with the possible undefined:
So, why can't we just turn on noUncheckedIndexedAccess? You can, but in a large codebase like that of Flux.ai, you are likely to get thousands of type errors. We had 2761 errors across 373 files! For one speedy engineer converting one file every minute, it would have taken 6+ hours of mind-numbing work to convert all 373 files.
The solution we describe here is how to smoothly convert your codebase with some simple heuristics and automation.
According to Wikipedia, a heuristic technique
is any approach to problem solving or self-discovery that employs a practical method that is not guaranteed to be optimal, perfect, or rational, but is nevertheless sufficient for reaching an immediate, short-term goal or approximation.
That is definitely true here.
The goal was to get the codebase compiling with the new flag, not to fix any bugs. The fixing can come later.
To that end, we intentionally added type assertions ! to suppress all new type errors from undefined types without changing the runtime behavior of the code.
Expanding the scope of replacements to preceding lines allowed us then to automate more fixes with few false positives.
The full script we ran on our codebase is below. Note: it did not fix all the errors. It fixed around 2400 out of 2761 errors, leaving around 100 files for us to fix by hand.
Pro-tip: when experimenting with the replacers and precede, you can simply reset your changes with git reset --hard HEAD (assuming you are working in a git repo).

A complete 555 timer guide covering pinout, internal operation, monostable and astable modes, timing calculations, and practical circuit examples. It also explains component selection and PCB layout tips for reliable designs.

A visual guide to capacitor schematic symbols, polarity markings, and specialized capacitor types. It explains how to choose the correct symbol and footprint to prevent assembly and design errors.

A practical guide to potentiometer wiring, including pin identification, voltage-divider and rheostat configurations, Arduino examples, and PCB footprint considerations. It helps designers avoid common wiring and layout mistakes.

A troubleshooting guide for DXF and SVG board-outline import failures, including open paths, unit mismatches, unsupported curves, and layer mapping issues. It shows how to clean CAD-to-EDA handoffs before PCB fabrication.

A practical guide to inverting op-amp circuits, covering how negative feedback creates inversion, how to calculate gain with Rin and Rf, and how real-world limits affect design. It also explains component selection and PCB layout practices for reliable amplifier performance.

A troubleshooting guide for common JLCPCB Gerber upload errors, including unreadable files, missing board outlines, drill-file issues, and Gerber X2 compatibility problems. It explains how to export and verify clean Gerbers before ordering.

A practical guide to designing PCB enclosures around board geometry, clearances, mounting, assembly, and 3D-printed prototyping. It also explains how Flux can generate prototype enclosures directly from a PCB project.

Decide between PCB patents and trade secrets. Learn how AI reverse-engineering impacts hardware IP and get a practical decision framework for founders.