What is tsconfig strict, and which sub-flag to relax for legacy?
Tests strict as a master switch and migration pragmatism. Strong answers name strictNullChecks or noImplicitAny as the first to relax in legacy code, trading null-safety for fewer errors. Red flag: disabling strict entirely instead of a targeted sub-flag.
WHAT THIS TESTS: Whether you understand that strict is a convenience switch that simultaneously enables a family of type-checking rules, and whether you can make a nuanced migration decision rather than treating type safety as binary. Interviewers want to see that you know the individual sub-flags exist and that you can weigh safety against delivery speed in a legacy context.
A GOOD ANSWER COVERS: First, define strict as the master switch that enables sub-flags including strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, alwaysStrict, strictBuiltinIteratorReturn, and useUnknownInCatchVariables. Second, explain that strictNullChecks and noImplicitAny are usually the most disruptive in legacy JavaScript code because they surface thousands of latent null and implicit any issues. Third, state that if you must disable one sub-flag first, strictNullChecks is often the pragmatic choice because it prevents the compiler from requiring null guards on every external API and DOM access, though the trade-off is losing compile-time null-safety and allowing potential runtime errors. Fourth, mention that noImplicitAny is another candidate because legacy code rarely has explicit types, but disabling it lets implicit any propagate silently through the codebase. Fifth, emphasize that you would never turn strict off entirely; you would disable one sub-flag, track the debt, and re-enable it file by file or module by module.
COMMON WRONG ANSWERS: Saying strict is just for better types without naming any sub-flags. Claiming you would disable strict globally to get the build passing. Picking a low-impact flag like strictBuiltinIteratorReturn as the first to disable, which misses the point of where the real migration pain lives. Failing to mention the trade-off at all, as if disabling a sub-flag is free.
LIKELY FOLLOW-UPS: How would you re-enable the flag incrementally? The answer should mention using per-file overrides, project references, or a strict tsconfig that new modules extend while legacy modules remain on the permissive config. What is the difference between noImplicitAny and strictNullChecks? noImplicitAny catches missing type annotations by inferring any, while strictNullChecks narrows the type system so null and undefined are not assignable to every type. How does strictFunctionTypes differ from the others? It makes function parameter checking stricter for callbacks, which is usually less noisy to enable early.
ONE CONCRETE EXAMPLE: Imagine migrating a 2016 Backbone codebase. With strictNullChecks enabled, every model.get call returns any or undefined and forces optional chaining or non-null assertions on hundreds of views. Disabling strictNullChecks lets the project compile so you can focus on annotating model shapes first. You keep noImplicitAny on so that new files without types still get flagged, and you add a lint rule or a backlog ticket to turn strictNullChecks back on once the core models are typed.
Read the original → typescriptlang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.