TypeScript Deep Dive
  • README
  • Getting Started
    • Why TypeScript
  • JavaScript
    • Equality
    • References
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Future JavaScript Now
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Project
    • Compilation Context
      • tsconfig.json
      • Which Files?
    • Declaration Spaces
    • Modules
      • File Module Details
      • global.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • Library QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • ESLint
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page
  • Suppressing Errors
  • Third Party JavaScript
  • Third Party NPM modules
  • External non js resources
  • More
  1. TypeScript's Type System

JS Migration Guide

Assuming:

  • you know JavaScript.

  • you know patterns and build tools (e.g. webpack) used in the project.

With that assumption out of the way, in general the process consists of the following steps:

  • Add a tsconfig.json.

  • Change your source code file extensions from .js to .ts. Start suppressing errors using any.

  • Write new code in TypeScript and make as little use of any as possible.

  • Go back to the old code and start adding type annotations and fix identified bugs.

  • Use ambient definitions for third party JavaScript code.

Let us discuss a few of these points further.

Note that all JavaScript is valid TypeScript. That is to say that if you give the TypeScript compiler some JavaScript -> the JavaScript emitted by the TypeScript compiler will behave exactly the same as the original JavaScript. This means that changing the extension from .js to .ts will not adversely affect your codebase.

Suppressing Errors

TypeScript will immediately start TypeChecking your code and your original JavaScript code might not be as neat as you thought it was and hence you get diagnostic errors. Many of these errors you can suppress with using any e.g.:

var foo = 123;
var bar = 'hey';

bar = foo; // ERROR: cannot assign a number to a string

Even though the error is valid (and in most cases the inferred information will be better than what the original authors of different portions of the code bases imagined), your focus will probably be writing new code in TypeScript while progressively updating the old code base. Here you can suppress this error with a type assertion as shown below:

var foo = 123;
var bar = 'hey';

bar = foo as any; // Okay!

In other places you might want to annotate something as any e.g.:

function foo() {
    return 1;
}
var bar = 'hey';
bar = foo(); // ERROR: cannot assign a number to a string

Suppressed:

function foo(): any { // Added `any`
    return 1;
}
var bar = 'hey';
bar = foo(); // Okay!

Note: Suppressing errors is dangerous, but it allows you to take notice of errors in your new TypeScript code. You might want to leave // TODO: comments as you go along.**

Third Party JavaScript

You can change your JavaScript to TypeScript, but you can't change the whole world to use TypeScript. This is where TypeScript's ambient definition support comes in. In the beginning we recommend you create a vendor.d.ts (the .d.ts extension specifies the fact that this is a declaration file) and start adding dirty stuff to it. Alternatively create a file specific for the library e.g. jquery.d.ts for jquery.

Consider the case of jquery, you can create a trivial definition for it quite easily:

declare var $: any;

Sometimes you might want to add an explicit annotation on something (e.g. JQuery) and you need something in type declaration space. You can do that quite easily using the type keyword:

declare type JQuery = any;
declare var $: JQuery;

This provides you an easier future update path.

Third Party NPM modules

declare module "jquery";

And then you can import it in your file as needed:

import * as $ from "jquery";

External non js resources

declare module "*.css";

Now people can import * as foo from "./some/file.css";

Similarly if you are using html templates (e.g. angular) you can:

declare module "*.html";

More

PreviousTypeScript's Type SystemNext@types

Last updated 5 years ago

Note: Well maintained and strongly typed definitions for nearly the top 90% JavaScript libraries out there exists in an OSS Repository called . We recommend looking there before creating your own definitions as we present here. Nevertheless this quick and dirty way is vital knowledge to decrease your initial friction with TypeScript**.

Again, a high quality jquery.d.ts exists at . But you now know how to overcome any JavaScript -> TypeScript friction quickly when using third party JavaScript. We will look at ambient declarations in detail next.

Similar to global variable declaration you can declare a global module quite easily. E.g. for jquery if you want to use it as a module () you can write the following yourself:

Again, a high quality jquery.d.ts exists at that provides a much higher quality jquery module declaration. But it might not exist for your library, so now you have a quick low friction way of continuing the migration 🌹

You can even allow import of any file e.g. .css files (if you are using something like webpack style loaders or css modules) with a simple * style declaration (ideally in a ):

If you want to be more silent about your upgrade because you couldn't get team buy in to move to TypeScript, .

DefinitelyTyped
DefinitelyTyped
https://www.npmjs.com/package/jquery
DefinitelyTyped
global.d.ts file
TypeScript has a blog post on upgrading silently without having to convince your team up front