Always use TypeScript
If you are writing a JavaScript code base you should use TypeScript, even if you are not writing TypeScript code.
Motivation
I am using React to create a website, it is an exchange: BQTX. We opted to not use TypeScript as a language, since my collegue is new to React and starting with React + TypeScript and a lot of new stuff to learn could be hard. Yes we are using only JavaScript (transpiled by Babel) but installing TypeScript and configuring it to check types is so easy, it takes no more than ten minutes and has huge benefits on our React code base.
Dependencies
Of course start installing TypeScript, and few dependencies you will need, for example if you are using React.
npm install typescript @types/react @types/react-dom --save-dev
Configuration
Create a tsconfig.json file like the following one.
{
"compilerOptions": {
"allowJs": true,
"charset": "utf8",
"checkJs": true,
"esModuleInterop": true,
"jsx": "preserve",
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"target": "esnext"
},
"exclude": [
"public"
],
"include": [
"src",
"test"
]
}
Note that I include the src and test folders where I put my source code and tests, and I exclude the public folder that contains my webapp, with JavaScript bundle and vendor libs. So edit the exclude and include arrays accordingly.
Now if you create this npm script in your package.json:
"tsc": "tsc"
you can launch TypeScrypt type checker with this command
npm run tsc
You may want to trigger it before every git commit using for example pre-commit git hook. If yes, just launch
npm install pre-commit --save-dev
And add this to your package.json:
"pre-commit": [
"tsc"
]
About tsconfig.json notice that:
- noEmit is set to
true
, it means that the TypeScript compiler will not output any transpiled code. - noUnusedLocals and noUnusedParameters are set to
false
initially.
You may want to make your type checker more strict by enabling these later options, maybe one at the time since it will raise many warnings.
- "noUnusedLocals": false,
+ "noUnusedLocals": true,
- "noUnusedParameters": false,
+ "noUnusedParameters": true,
Defining types
You can use JSDoc markup to define types. In particular with @typedef
you can define new types, for example
import React from 'react'
/**
* @typedef {Object} MyButtonProps
* @prop {React.ReactNode=} children
* @prop {boolean=} disabled
*
* @param {MyButtonProps} props
*/
export default function MyButton ({
children,
disabled
}) {
return (
<button
disabled={disabled}
>
{children}
</button>
)
}
Bonus Tip: if you need shared types definition, you can create a types.js containing only JSDoc comments. You need to import it in your entry file, for instance src/index.js.
Benefits
There are many benefits you get by adding TypeScript as a type checker, but the best one in my opinion is the following.
You will catch errors at Compile Time.
Yes this is the thing I like most about TypeScript, it complains at Compile time, I mean before you generate your JavaScript bundle, and
it is far better then your Website user discovering the same error at Run Time.