In the last decade, browsers have become very powerful, allowing developers to build rich interactive applications. The interactivity and richness have come with an increase in complexity and size of the codebase in the frontend. Large complex codebases demand more attention and frontend teams have become larger.
When more than one developer collaborates, there is a requirement of clear interfaces and APIs. JavaScript is very flexible, but you cannot deduce the type of arguments a function would accept.
e.g., What do you think print
function’s argument type is?
function print(value) {
console.log(value)
}
The type of value
is ambiguous, even after looking at the source code of the print
function which poses problems in large codebases where you cannot afford to jump into the source to deduce argument type of a function. One way to resolve this issue is to document the function’s API, but docs have a tendency of getting outdated.
What if there were a way to know a function’s argument types by just glancing over the function name?
Yes, there is a way: types or TypeScript.
function print(value: string) {
console.log(value)
}
As soon as we look at the print
function, we know value
should be a string. That little information immediately boosts collaboration and productivity.
In some sense, types make APIs self-documenting. Apart from this, code editors/IDEs also benefit a lot from types. IDEs can provide intelligent suggestions, and display type mismatches inline.
Any application that can be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript, will eventually be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript.> Any application that can be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript, will eventually be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript.#### So TypeScript is it?
TypeScript makes interfaces explicit and enables collaboration, but it comes with its complexity and downsides.
Vue provides a fluent object-based API for authoring composable components.
Todo.js
export default {
data() {
return {
items: []
}
},
methods: {
add(text) {
this.items.push({ text, done: false })
},
complete(index) {
this.items[index].done = true
}
}
}
The above component can be written in TypeScript as:
Todo.ts
import { Component, Vue } from 'vue-property-decorator';
interface TodoItem {
text: string
done: boolean
}
@Component
export default class Todo extends Vue {
private items!: TodoItem[]
private add(text: string) {
this.items.push({ text, done: false })
}
private complete(index: number) {
this.items[index].done = true
}
}
With TypeScript, you get type based intellisense which boosts developer productivity.
TypeScript support in Vue was an afterthought, and it becomes quite verbose in real-world applications. Good thing is that’s going to change with Vue 3 coming mid-next year.
Adding types to Vuex is even more complex and unpleasant. Also, the intellisense on state/getter/actions mapped to components is almost non-existent.
Any application that can be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript, will eventually be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript.> Any application that can be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript, will eventually be written in J̶a̶v̶a̶S̶c̶r̶i̶p̶t̶ TypeScript.
Yes, that’s true, and tools like ESLint are far more helpful in catching these bugs.
Maybe but you don’t need to jump on it today. TypeScript ensures type safety, documents API interfaces and enables intellisense in IDEs. I feel intellisense is far more critical in Vue application projects than type safety.
The best thing about TypeScript is that you can take advantage of TypeScript without using TypeScript.
Yes, with VS Code and TypeScript, we can get intellisense in JavaScript files. We can enforce type safety too if we want that. VS Code infers JSDoc annotations to generate TypeScript definition on the fly. Let’s set up a JavaScript project with types and intellisense.
In JavaScript files, VS Code infers types for static values to provide intellisense, including object property names, function return value type, and property types.
VS Code has automatic type acquisition which uses npm package’s bundled types or community types from DefinitelyTyped to provide intellisense, including method signature and parameter info. Also, using Vue’s type information and Vetur plugin, it can provide rich completions and type information in .vue
files too.
However, static type inference for array literals and dynamic values is not possible, for such cases, VS Code can use JSDoc annotations to collect type information. In the following snippet, type of this.items
is detected as an array
of type any
, as it’s known statically that this.items
is an array, but there is no information about values in the array. We can use a@type
annotation for adding type information to this.items
, @type
allows adding type information, similar to any typed language (or TypeScript).
VS Code type inference from JSDoc comments is as reasonable as TypeScript. See the following code snippets written in JavaScript and TypeScript.
Vue component options have data
, props
, computed
and methods
which when provided with type information can significantly improve the developer experience.
1\. Data
We have to provide @type
annotations for properties which are impossible infer statically. e.g.:
In the above snippet, items
and currentItem
have incomplete type information, so we need@type
annotations only for those two properties.
Type definitions for items
and currentItem
are quite similar. If we were writing TypeScript, we would have created an interface for the item type. With JSDoc, we can define custom types or interfaces using a@typedef
annotation.
Autocomplete suggestions and type information for data
are available on this
context in life-cycle hooks, methods, computed and watch handlers.
For primitive props, VS Code can infer type information automatically.
However, if you have Object
or Array
as the type, then auto-inferred type information is useless. In such cases, we have to provide type information with a @type
annotation.
It even works with the validator options syntax for props.
When defining prop names as an array, it’s a little complex to provide type information. It is discouraged to use names array for props definition.
For computed properties, automatic return type inference does not work as expected but it does provide computed property names in suggestions.
So with a @returns
annotation, we can provide type information for the returned value as well.
Method names are available in VS Code suggestions on this
context, but they lack type information.
Here, we see the add
method accepts one parameter text
and returns a number
, the auto inferred information is already beneficial, and if we can provide type information for the text
parameter, we get the complete experience of a typed language. Moreover, we can add types to parameters using the @param
annotation.
We can even provide a small description of the method if it’s not clear from its name.
VS Code supports even more JSDoc annotations; you can find the complete list of supported annotations on the VS Code wiki page.
Yes, it’s possible, add // @ts-check
at the start of the script in .vue
file.
If you want to enable strict type checks in the whole project, then you should add a jsconfig.json
file to the project root.
{
"compilerOptions": {
"checkJs": true
}
}
You can find more options at the [jsconfig.json]([https://code.visualstudio.com/docs/languages/jsconfig)](https://code.visualstudio.com/docs/languages/jsconfig) "https://code.visualstudio.com/docs/languages/jsconfig)")
reference.
Learn more
☞ Learn Web Development Using VueJS
☞ Learn by Doing: Vue JS 2.0 the Right Way
☞ Vue.js 2 Essentials: Build Your First Vue App
☞ Getting started with Vuejs for development
☞ Horizontal Feed Component with Sass and VueJs 2
#vue-js #javascript