Is it possible to get the benefits of type checking without TypeScript's syntax? Absolutely
TypeScript lets you annotate your JavaScript with type annotations. It can even check these for errors in build-time, so you can catch errors before they get deployed to production. You’ll never have to deal with another undefined is not a function error ever again!
TypeScript, by default, requires you to make a few changes to your build setup. You’ll need to rename your JavaScript files to .ts
and .tsx
, and either use tsc
(the TypeScript Compiler) or Babel (with preset-typescript) to compile them.
In this article:
Working with TypeScript means having to use a new syntax, even if it’s a strict superset of JavaScript. Many developers don’t like having to deal with a new syntax. If this describes you, then this article is for you.
TypeScript can read JSDoc’s type annotations. While JSDoc is primarily used as a means of writing documentation, TypeScript types can be written with JSDoc syntax as well. This means anyone can take advantage of TypeScript’s type checking in JavaScript without having to convert JavaScript code to TypeScript.
It’s a great idea to use JSDoc whether you use TypeScript or not. It’s the de facto standard for documenting JavaScript, and is supported by a lot of tools and editors. If you’re using JSDoc to document your JavaScript, you might as well let TypeScript enforce the integrity of your types in your code.
InstallTypeScript. We’ll need TypeScript to get started. Install the typescript npm package in your project to get started.
Enable JSDoc type checking. Configure TypeScript to check your JavaScript files. (By default, TypeScript only checks .ts
files.) TypeScript is configured using the tsconfig.json
file. We’ll also be using the noEmit
option, since we’re only going to be using TypeScript as a type checker.
Try it. Run tsc
to check your project’s types. It’s recommended to add this to your CI, too, so you can automatically enforce it in your project’s changes.
Use @param
to document types of a function’s parameters. You’ll need to put these in JSDoc comments, which are block comments that begin with two stars.
JSDoc is, first and foremost, a documentation tool. Aside from adding type annotations, we might as well use it to document what your functions do.
Properties of params can be documented. This can be used to document React props in function components, too.
Add an equal sign at the end of a type to signify that it’s optional. In this example, number=
is the same as number | null | undefined
. This special syntax (“closure syntax”) is only available in JSDoc types.
Use @type
to provide inline types to variable declarations. This isn’t typically needed for constants, as TypeScript can usually infer types pretty well. It’s a great fit for non-constant variables, though (ie, let).
@type
can also be used to provide inline type definitions to function arguments. Great for anonymous functions.
Complex, reusable types are better defined in an external TypeScript file. Types can be defined in an external .d.ts
file, then import them into JavaScript using @typedef {import(...)}
.
Use @typedef
to define a type. External .d.ts
files are preferred to this approach, but this syntax is available should you need it.
Use union types (|
) to signify types that can be one or another. This, along with almost any TypeScript type, can be used in a @typedef
.
The JSDoc syntax isn’t as expressive as the TypeScript syntax, but it comes very close. There are also some other advanced TypeScript features that are available in JSDoc: The official JSDoc in TypeScript documentation has details on these features and more.
@template
@returns
@returns
@callback
@enum
Function components are plain functions. You can document them in any of the ways we previously learned to document functions. In this example, we’ll document them using object types.
Use @extends
to define the types for your props and state. You can then use @typedef
(either inline or imports) to define what Props and State are.
Documenting functions: Write documentation as block comments that begin with a double-star. Document parameters with @param
.
Importing type definitions: Import type definitions with @typedef
and import
. This allows writing type definitions in external TypeScript files.
Optionals: Use the equal sign to denote nullable types. This is equivalent to User | null | undefined
.
Anonymous functions: Use @type
to document parameters of an anonymous function.
Documenting options: You can document the properties of object parameters.
I am a web developer helping make the world a better place through JavaScript, Ruby, and UI design. I write articles like these often. If you'd like to stay in touch, subscribe to my list.