Your codebase,
checked before it runs
We build and move codebases in TypeScript, from JavaScript and loose settings to strict ones, and onto TypeScript 7, the native compiler, so your team finds more mistakes before they reach production.
Thanks, we’ll be in touch soon.
{{ heroStatus }}
You’re in good company
A few of the companies we’ve worked with.
When the compiler takes it on trust
TypeScript checks what it can see, before the code runs. Where code is still JavaScript, is typed as any, has its checks silenced in a comment, or reads data from outside, the compiler takes each value on trust. So a codebase can build cleanly and still fail where its types and its data disagree.
An older configuration needs work too. TypeScript 6.0 changed several defaults and deprecated a list of older options, and TypeScript 7, the native compiler, stops with an error on every option 6.0 deprecated. How much that touches varies with each tsconfig.json, the file that holds a project’s settings, and the tools around it.
Without knowing where the checks stop, a change can reach further than anyone can see. So the work starts with a map: where the codebase is checked, where it isn’t, and what each setting does today.
What we build
Every change runs through the type check and the tests before anyone reviews it, and every setting we change is tried on a branch first, so the code you ship keeps building while the work goes on.
New codebases in TypeScript
Front ends and back ends written in TypeScript, strict from the first commit, sharing the types for the data they pass between them, with one set of settings the whole codebase follows.
JavaScript moved to TypeScript
File by file, beside your feature work, as TypeScript’s docs describe: the JavaScript brought into the project as it is, then each file moved across and checked. Code typed through JSDoc comments is checked against what TypeScript 7 changed for it before it matters.
Strict, one check at a time
From loose settings, any and checks silenced in comments, to strict ones. Each check in the strict family is a setting of its own, so we turn them on one at a time and fix what each one finds rather than silencing it.
Upgrades to TypeScript 6.0 and 7
Deprecated options replaced and the new defaults set, until the build is clean on 6.0 with no deprecation warnings, then the same code built on 7. Each step is tried on a branch, a copy of the code kept apart from the one you ship, first.
Faster type checks
The type check moved to the native compiler wherever your tools allow it, with project references for large codebases and monorepos, so each part builds on its own.
Types at the edges
Types for your APIs generated from the schemas that describe them, and the data that arrives through them checked where it enters, against the same schema.
TypeScript on Node.js
Services run straight from their TypeScript files on Node.js where its type stripping fits, which takes erasable syntax only. Node.js blanks out the types and checks nothing, so the type check still runs on every change.
Checks on every change
The type check and the tests run on every change, in the pipeline your team already uses, and a change merges once both pass.
AI where it helps
Changes from AI coding assistants go through the same type check and tests before anyone reviews them, and a person decides what merges.
- The framework itself:React & Next.jsAngularVue.js & NuxtNode.js
- Older JavaScript, a part at a time:Legacy Modernization
- The tests a change is checked against:QA & Test Automation
- Connecting your systems:Systems & API Integration
- Developers in your own team:Hire developers for TypeScript codebases
Onto the native compiler, through 6.0
TypeScript 7 is the same compiler ported to native code, built to check code the way 6.0 does. It takes on 6.0’s new defaults and stops with an error on every option 6.0 deprecated, so the route to 7 runs through a clean build on 6.0.
Some tools wait for now. Files that embed TypeScript, in Vue, Svelte, Astro or MDX, need 6.0 for now; Angular projects can use 7 for the type check from the command line and 6.0 in the editor; and tools that load the compiler themselves keep 6.0 beside 7 until TypeScript 7.1, now in beta, brings them a new API.
So we check every setting and every tool before the move, and keep 6.0 wherever a tool still needs it. Check an option from yours.
baseUrl
In TypeScript 6.0: Deprecated, and no longer a root for finding modules.
In TypeScript 7: Not supported: each paths entry is written relative to the project instead.
target
In TypeScript 6.0: Left unset, it follows the newest ECMAScript version TypeScript supports.
In TypeScript 7: The same moving default.
target: es5
In TypeScript 6.0: Deprecated: the lowest target is now ES2015.
In TypeScript 7: Not supported: ES5 output needs another compiler.
downlevelIteration
In TypeScript 6.0: Deprecated, since it only ever changed ES5 output; setting it at all is flagged.
In TypeScript 7: Not supported, so the setting comes out.
moduleResolution
In TypeScript 6.0: node, also called node10, and classic are deprecated.
In TypeScript 7: Neither is supported: nodenext for code Node.js runs, or bundler for code a bundler builds, as Microsoft recommends.
module
In TypeScript 6.0: Left unset, it’s esnext.
In TypeScript 7: The same default.
module: amd, umd, systemjs or none
In TypeScript 6.0: amd, umd, systemjs and none are deprecated.
In TypeScript 7: None of them is supported: esnext or preserve, with a bundler, as Microsoft recommends.
outFile
In TypeScript 6.0: Deprecated and taken out: joining files into one output is left to a bundler.
In TypeScript 7: Not supported, like every option 6.0 deprecated.
esModuleInterop
In TypeScript 6.0: Can no longer be set to false: the safer interop is always on.
In TypeScript 7: Always on; setting it to false is an error.
allowSyntheticDefaultImports
In TypeScript 6.0: Can no longer be set to false: the safer interop is always on.
In TypeScript 7: Always on; setting it to false is an error.
alwaysStrict
In TypeScript 6.0: Can no longer be set to false: all code is treated as JavaScript’s strict mode.
In TypeScript 7: Always on; setting it to false is an error.
strict
In TypeScript 6.0: On by default. A codebase that relied on it being off now sets it to false.
In TypeScript 7: On by default, as in 6.0.
types
In TypeScript 6.0: An empty list by default, so the global type packages a project needs are listed by name.
In TypeScript 7: The same empty default.
rootDir
In TypeScript 6.0: Defaults to the folder holding tsconfig.json, so a project with its code in a subfolder sets it.
In TypeScript 7: The same default.
noUncheckedSideEffectImports
In TypeScript 6.0: On by default, to catch typos in imports made only for their side effects.
In TypeScript 7: On by default, as in 6.0.
libReplacement
In TypeScript 6.0: Off by default.
In TypeScript 7: Off by default, as in 6.0.
ignoreDeprecations
In TypeScript 6.0: Set to “6.0”, it silences 6.0’s deprecation warnings, in 6.0 only.
In TypeScript 7: It changes nothing: 7 supports none of the deprecated options, so each is replaced before the move.
stableTypeOrdering
In TypeScript 6.0: A flag that orders types the way 7 does, to compare the two; it can slow the type check, and isn’t meant to stay on.
In TypeScript 7: Always orders types that way, and can’t be turned off.
{{ nvTyped }}
In TypeScript 6.0: Microsoft’s release post lists no change to this option.
In TypeScript 7: Microsoft’s release post lists no change to this option.
Type an option, or pick one from the list.
Every move to TypeScript 7 we plan starts with a clean build on 6.0, as Microsoft encourages.
{{ nvStatus }}
Where the types end
Types are checked before the code runs, and they’re gone when it runs: the compiler leaves them out of what it builds, and Node.js, running TypeScript directly, replaces them with blank space.
So they can’t check what arrives while the code runs: an API’s response, a form, a file, a message from another system. The code treats it as the type it expects, whatever it holds.
So we check that data where it enters, against the same schema its types are generated from, so the types and the checks can’t drift apart.
Start with the settings and the edges
The review covers each codebase: its TypeScript version, each tsconfig.json and what it sets, and where the type check runs, in the editor, in CI or in the build; how strict it is, which strict checks are on, where any and type assertions are used and where checks are silenced in comments; the JavaScript still in it and how that’s checked; the options 6.0 deprecated or changed, against each tsconfig.json; the tools that load TypeScript themselves, such as lint rules that read types, build loaders and framework template checkers, and which of them need 6.0 for now; the build, its project references and the monorepo’s layout, with the type check timed today as a baseline for the review; the data at the edges, where it enters, whether it’s checked while the code runs, and whether its types are generated or written by hand; the Node.js versions in use, where type stripping is being weighed; and the tests, which exist and what a change is checked against now.
We begin with one of four first steps, each tried on a branch: the build made clean on TypeScript 6.0 with no deprecation warnings, one strict check turned on in one package with what it finds fixed, one module moved from JavaScript to TypeScript, or the type check run on TypeScript 7 beside 6.0 in CI.
What you receive is a written review and a proposal for that first step.
Questions worth asking
Should we move our JavaScript to TypeScript?
It depends on the codebase and how often it changes: one that changes often has more to gain than one that rarely moves. TypeScript’s docs describe moving a project file by file, so the move can run beside feature work, starting where changes carry the most risk. We set out what a move would involve for yours, and the choice and its timing stay yours.
Can we move to TypeScript 7 now?
It depends on your toolchain. Microsoft says practically any code that builds cleanly on 6.0, with no deprecations silenced, should build the same way on 7. Angular projects can use 7 for the type check from the command line and 6.0 in the editor; files that embed TypeScript, in Vue, Svelte, Astro or MDX, need 6.0 for now; and tools that load the compiler themselves keep 6.0 beside 7 until 7.1, now in beta, brings them a new API. We check each tool before anything moves.
What changed in TypeScript 6.0, and do we have to act on it?
Several defaults changed: strict checks are on, the module format and the target follow current JavaScript, and global type packages are listed by name. A list of older options was deprecated. On 6.0 those warnings can be silenced for now, but TypeScript 7 supports none of the deprecated options, so we replace them on a branch before the move. 6.0 is a stable release in its own right, and Microsoft supports running it beside 7.
Will TypeScript 7 make our builds faster?
Microsoft reports large speedups on full builds, with results that differ from one codebase and machine to the next. We time your type check before the move and after it, on the same machines, so you see what it means for yours.
Does strict mode mean rewriting our code?
No. Each check in the strict family is a setting of its own, so we turn them on one at a time, area by area, and fix each finding where it’s found. Many fixes are small: a value that can be empty handled, or a type written down where it was guessed.
Can Node.js run our TypeScript without a build step?
In part. Current Node.js releases run TypeScript files that use only erasable syntax, the parts that can simply be taken out, by replacing the types with blank space. They don’t check the types and they ignore tsconfig.json, so the type check stays in CI. We tell you which of your code fits, and what the rest would take.
Do types replace tests?
No. Types check the shape of a value, such as a number where a number belongs; tests check what the code does with it. We keep both on every change.
How do we keep the front end and back end in step?
Generate the types for each API from the schema that describes it, and check the data that arrives against that same schema where it enters. When the API changes, the type check points to the places in the typed code the change reaches.
Can AI assistants help with the move?
Yes, within the same checks as any other change. Assistants can draft the repetitive parts, such as the types for a file being moved, and each change still goes through the type check, the tests and a person’s review before it merges.
Can you take over our existing codebase?
Yes. Before changing anything, we read the code, its settings and its build, name an owner for each part, and agree one first piece of work with you. Where your team has developers of its own, we work alongside them.
How do you keep our code secure?
We keep dependencies current, check data where it enters, and give each part of the system only the access it needs. Types help while the code is written, but they’re gone when it runs, so the checks at the edges do that work.
What does it cost?
It depends on your codebases, their settings and tools, and which first step you choose. Before any work starts, you get a written proposal with the scope, the price or rate, and how you pay.
Can we hire developers for our own team?
Yes. Within 48 hours of your request we introduce developers who know TypeScript codebases and work in your time zone. You meet them first, and decide who joins.
Microsoft is a trademark of the Microsoft group of companies. Webair is independent of Microsoft, and isn’t sponsored by, endorsed by or affiliated with it.
Let’s build it better
Tell us which TypeScript version and settings each of your codebases runs on. We’ll agree on a first step in a short call.
Thanks, we’ll be in touch soon.
{{ ctaStatus }}