Typechecking Non-React Code
When you build a component in React you have the option to explicitly declare the type of props that it can, or must, accept by using the prop-types
library.
This may seem like pointless extra work when you’re starting out, but when you begin working with other people declaring your props is a fantastic way to communicate how a component can be used and what it needs to work.
What you probably didn’t know is that Typechecking also make your code run faster. The V8 engine in chrome has something called Ignition, which is an interpreter. If your code consistently runs without type errors then V8 will skip the interpretation process and jump straight to turbo. Break the rules once and all your code will need to be interpreted from that point onwards. Strongly typed code runs in the fast lane.
The ‘prop-types’ library works for react code but it doesn’t work with all the non-react javascript files in a project.
The popular solutions involve using Typescript
or Flow
. Typescript involves some setup with a react project, and flow works out of the box. The only problem is that you have to commit to one or the other.
On the other hand, if you use VS Code you can add comments that will do all the typechecking for you.
VS Code comments provide a lot of the benefits of Typescript but let you write regular react code that anyone can read.
All you have to do is add the following comment to the top of the file that you want to typecheck //@ts-check
.
Then when you declare a variable you can add a comment above it declares its type like so:
/** @type {string} */
let someString;
If you then re-assign the someString
variable to anything but a string it will throw an error in VS Code’s terminal.
You could declare parameters and returns on functions like so:
/** @param {number} x */
/** @param {number} y */
/** @return{number} */
let add = (x, y) => x + y
};
If you don’t want to have to write each element out on their own line a more concise way of doing the same is:
/** @type {(x: number, y: number) => number} */
let add = (x, y) => x + y
};
If you need to declare something a bit more complicated that a single boolean, string or number then you can arrange objects or arrays like so:
/** @param {{name:string, friends: string, friendCount: number, uid: number }} group */
/** @param {string} friend */
addFriendToGroup = (group, friend) => {
let group = this.state.group;
group.friends.push(friend);
this.setState({ group });
};
In the example above the friend
parameter is just a string. In most cases it would probably be an object. Instead of having to rewrite this again and again you can define the friend parameter as a new type at the top of a file like so:
/**
* @typedef {Object} Friend
* @prop {string} name
* @prop {string} uid
*/
Then you can refer to it as you would any other type:
/** @param {{name:string, friends: Friend[], friendCount: number, uid: number }} group */
/** @param {Friend} friend */
addFriend = (group, friend) => {
let group = this.state.group;
group.friends.push(friend);
this.setState({ group });
};
There is much more you can do with type comments but that should be enough to get started.
I’m enjoying this new feature and will continue to update this post when I learn useful new stuff.
The best thing about using comments is that if someone isn’t using VS Code then your type definitions just look like harmless comments.
Links
- There is some excellent documentation on the typescript website.
- For more on how you can use VS Code comments check out the write up on Type Checking JavaScript Files.
- Mike North did an excellent frontend master’s course on all the cool things you can do with VS Code, here is the write up on VS Code comments section.
- Also found a great intro on but not least, the docs on using Bryce Dooley’s blog](https://brycedooley.com/type-checking-without-typescript/).
- Last but not least, the docs on using React’s own
prop-types
library.