Clarvo Blog·Programming

From JavaScript to TypeScript: Project Setup, Compiler and a Safe First Migration

Learn what the TypeScript compiler does, configure tsconfig, move a JavaScript file to TypeScript and separate type-level ideas from runtime code.

Clarvo
Clarvo Editorial Team
9 min read·21 Sept 2026·454 words
From JavaScript to TypeScript: Project Setup, Compiler and a Safe First Migration
Source image via the referenced Medium article ↗

1. Start with JavaScript that already works

user.js — before migrationjs
export function fullName(user) {
  return `${user.firstName} ${user.lastName}`;
}

export function ageNextYear(user) {
  return user.age + 1;
}

2. Add TypeScript locally

Install compilerbash
npm install --save-dev typescript
npx tsc --init

3. Understand tsc versus Babel

ToolPrimary jobType-checks TypeScript?
tscType checking + JavaScript emitYes
BabelSyntax transformationNot by itself
ESLintStatic lint rulesNot a TypeScript compiler

Some build tools can strip TypeScript syntax without doing a full type check. Keep a dedicated type-check command in CI when your bundler is not using tsc for that responsibility.

4. Rename one file, then type the inputs

user.ts — first migrationts
type User = {
  firstName: string;
  lastName: string;
  age: number;
};

export function fullName(user: User) {
  return `${user.firstName} ${user.lastName}`;
}

export function ageNextYear(user: User) {
  return user.age + 1;
}

5. Turn on useful strictness

tsconfig.json excerptjson
{
  "compilerOptions": {
    "strict": true,
    "noEmit": true,
    "target": "ES2022",
    "module": "ESNext"
  }
}

6. Replace any with a real decision

SituationBetter type
You know the exact object shapeinterface or type
Several allowed primitivesunion
Truly unknown external valueunknown
Generic reusable containergeneric type parameter
You are temporarily bypassing checksany — but document and remove it

7. Runtime data needs runtime checks

Narrow unknown JSON manuallyts
function isUser(value: unknown): value is { name: string; age: number } {
  if (!value || typeof value !== 'object') return false;
  const item = value as Record<string, unknown>;
  return typeof item.name === 'string' && typeof item.age === 'number';
}

const data: unknown = await response.json();
if (!isUser(data)) throw new Error('Invalid user response');

8. Migrate boundaries before internals

  1. 1
    API models

    Type request and response shapes first.

  2. 2
    Shared domain objects

    Users, products, payments, exam records.

  3. 3
    Utility functions

    Small functions are easy to migrate and test.

  4. 4
    UI components

    Move props and state once shared data types are stable.

  5. 5
    Strictness cleanup

    Reduce casts and temporary any types after the app compiles.

9. Let JavaScript and TypeScript coexist when needed

TypeScript can support gradual adoption. In large systems, a mixed period can be healthier than a big-bang rewrite. Use allowJs/checkJs deliberately if it fits your build, and keep the migration plan visible.

10. Migration checklist

  • ✓npm run typecheck exists and runs in CI.
  • ✓External API data is not trusted only because an interface exists.
  • ✓No new any types are added without a reason.
  • ✓Compiler target/module settings match the runtime/build tool.
  • ✓The application is still tested after each migration slice.
  • ✓Source maps and production monitoring still work.

Official TypeScript resources

Sources and further reading

Clarvo articles are independently written. These references let you inspect the original inspiration and primary or official sources used to deepen the guide.

  1. Source inspiration — Learn TypeScript in Minutes — Part Onemedium.com