From JSDoc to TypeScript:
JSDoc: Structuring creativity
JavaScript, a language of freedom, where creativity knows no bounds 😆
Let's channel this creativity with JSDoc for clarity and guidance 🤓
# CHAPTER 1
What is JSDoc?
- JSDoc is a markup language for documenting JavaScript code.
- Allows generation of HTML documentation from source code comments.
- Supports tags to detail code's structure, purpose, and behavior.
- Enhances readability, maintainability, and collaboration among developers.
- Facilitates code insights in IDEs and supports type checking.
The Significance of JSDoc
Facilitating Onboarding
Accelerates the onboarding process for new developers, enabling them to grasp the functionality and architecture of large-scale JavaScript projects rapidly.
1.
2.
Enhancing Team Collaboration
Fosters better understanding and collaboration within development teams.
3.
Sustainable Development
Supports long-term project sustainability by making the codebase more navigable and easier to maintain, even as team members change over time.
# CHAPTER 1
// Normal Javascript Comment 1
/* Normal Javascript Comment 2 */
/**
JSDoc containing two asterisks
*/
# PRESENTING CODE
JSDoc comment
Two types of tags
# CHAPTER 1
-
Block Tags: Sit at the top level of a JSDoc comment. Start with
@
and are followed by a newline, except for the last block tag in a comment.
-
Inline Tags: Embedded within the text of a block tag or description. Begin with
@
and are enclosed in curly braces{}
. Use a backslash\
to escape curly braces within the tag text. Newlines are not required after inline tags.
/**
* @type {number}
*/
var FOO = 1
/**
* @const {number}
*/
const FOO = 1
/**
* @type {Array<string>}
*/
const colours = ['red', 'blue', 'green']
# JSDoc cheatsheet
Variables
/**
* This is a function.
*
* @param {string} n - A string param
* @param {string} [o] - A optional string param
* @param {string} [d=DefaultValue] - A optional string param
* @return {string} A good string
*
* @example
*
* foo('hello')
*/
function foo(n, o, d) {
return n
}
# JSDoc cheatsheet
Functions
# JSDoc cheatsheet
Types
/**
* A song
* @typedef {Object} Song
* @property {string} title - The title
* @property {string} artist - The artist
* @property {number} year - The year
*/
/**
* Plays a song
* @param {Song} song - The {@link Song} to be played
*/
function play(song) {}
# JSDoc cheatsheet
Typedef
/**
* A song
* @typedef {{
* title: string,
* artist: string,
* year: number
* }} Song
*/
/**
* Plays a song
* @param {Song} song - The {@link Song} to be played
*/
function play(song) {}
# JSDoc cheatsheet
Typedef Shorthand
/**
* @typedef {import('./Foo').default} Bar
*/
/**
* @param {Bar} x
*/
function test(x) {}
# JSDoc cheatsheet
Importing types
/**
* Adds two numbers
* @param {number} a - The first number
* @param {number} b - The second number
*/
function add(a, b) {
return a + b;
}
/**
* @param {number} a - The first number
* @param {number} b - The second number
* @description Adds two numbers
*/
function add(a, b) {
return a + b;
}
# JSDoc cheatsheet
Tag @description
// The @param tag is used to specify the name (required),
// type, and description of a function's parameter.
// The syntax is:
// @param {Type} Name - Description.
// The parameter type can be a native JavaScript type,
// and expressions can be used to indicate if a parameter
// is non-nullable or an array.
/**
* Greets a user
* @param {string} name - The user's name
*/
function sayHello(name) {
alert('Hello ' + name);
}
# JSDoc cheatsheet
Tag @param
// The @returns tag is used to describe
// the value that a function returns.
//
// The syntax is:
// @returns {Type} Description.
/**
* Adds two numbers
* @param {number} a - The first number
* @param {number} b - The second number
* @returns {number} The sum of numbers a and b
*/
function add(a, b) {
return a + b;
}
# JSDoc cheatsheet
Tag @returns
/**
* Divides two numbers
* @param {number} a - The numerator
* @param {number} b - The denominator, must not be 0
* @throws {Error} If the denominator is 0,
* an error is thrown indicating division by zero
* is not allowed.
* @returns {number} The result of the division a / b
*/
function divide(a, b) {
if (b === 0) {
throw new Error('Division by zero is not allowed.');
}
return a / b;
}
# JSDoc cheatsheet
Tag @throws
/**
* Fetches data from a URL asynchronously
* @async
* @param {string} url - The URL to fetch data from
* @returns {Promise<Object>} A promise resolving to
* the data fetched from the URL
*/
async function fetchData(url) {
const response = await fetch(url);
return response.json();
}
# JSDoc cheatsheet
Tag @async
/**
* Possible title for this talk
* @type {string}
* @author Exiliot [exiliot@example.com]
*/
const talkTitle = "Demystifying JSDoc"
# JSDoc cheatsheet
Tag @author
/**
* Sums of the square of two numbers a**2 + b**2
* @example <caption>How to use the sumSquares function</caption>
* // returns 13
* sumSquares(2, 3)
* @example
* // returns 41
* sumSquares(4, 5)
* // Typing the function
* @param {number} a - The first number
* @param {number} b - The second number
* @returns {Number} Returns the sum of the squares
* */
const sumSquares = function(a, b){
return a**2 + b**2
}
# JSDoc cheatsheet
Tag @example
/**
* @version 1.0.0
* @type {number}
**/
const meaningOfLife = 42
# JSDoc cheatsheet
Tag @version
/**
* How to use the link tags
* Also see the {@link https://jsdoc.app/tags-inline-link.html official docs} for more information
* @tutorial getting-started
**/
function myFunction (){
}
# JSDoc cheatsheet
Tag @link
Work with React
/**
* Represents a greeting component that displays a welcome message.
*
* @component
* @param {Object} props - The properties passed to the component.
* @param {string} props.name - The name of the person to greet.
* @returns {JSX.Element} A greeting message wrapped in a <div>.
*/
const Greeting = ({ name }) => <div>Hello, {name}!</div>;
# JSDoc cheatsheet
Functional component
import React from 'react';
/**
* @typedef Props
* @prop {React.ReactNode} title
* @prop {React.ReactNode} [desc]
* @prop {React.ReactNode} [selectFlightPrompt]
* @prop {()=>void} [onLogin]
*/
/**
* @param {Props} props
*/
const InflowHeader = ({ title, desc, selectFlightPrompt, onLogin }) => (
...
);
# JSDoc cheatsheet
Functional component
/**
* @typedef Props
* @prop {any} resource
*/
/**
* @typedef State
* @prop {boolean} isDrawerOpen
*/
# JSDoc cheatsheet
Class component
/**
* @extends Component<Props, State>
*/
class SampleContainer extends Component {
/** @type {State} */
state = {
isDrawerOpen: false,
};
constructor(props){
super(props);
}
render() {
return <>...</>;
}
}
# JSDoc cheatsheet
Class component
/**
* Custom hook for managing and toggling boolean state.
*
* @returns {[boolean, () => void]} Current state and
* a function to toggle the state.
*
* @example
* const [isOpen, toggleOpen] = useToggle(false);
*/
const useToggle = (initialState = false) => {
const [state, setState] = useState(initialState);
const toggle = () => setState(!state);
return [state, toggle];
};
# JSDoc cheatsheet
Hook
/**
* Custom hook for managing and toggling boolean state.
*
* @typedef {Object} HookResult - The result of the hook.
* @property {boolean} state - The current boolean state.
* @property {Function} toggle - Function to toggle the
* state.
*
* @param {boolean} [initialState=false] - The initial state.
* @returns {HookResult} Current state and a function to
* toggle the state.
*/
const useToggle = (initialState = false) => {
const [state, setState] = useState(initialState);
const toggle = () => setState(!state);
return [state, toggle];
};
# JSDoc cheatsheet
Hook
JSDoc + IntelliSense = ♥️
# JSDOC + IntelliSense
Typehinting in VSCode with JSDoc help
# JSDOC + IntelliSense
Using @typedef to define custom type definitions
JSDoc vs TypeScript
JSDoc and TypeScript both solve the problems with writing and maintaining plain JavaScript code.
However, they used different approaches, which have their benefits and drawbacks.
Benefits of JSDoc over TypeScript
Flexibility & Compatability
JSDoc being just JS comments, means it could be added to any JS codebase regardless of the language version, and it is not tied to a compiler like TypeScript is.
1.
2.
Code Annotation
JSDoc could be used for more than just type checking. It could be used to add more documentation, describe how functions work, and generate a documentationwebsite, all providing value to enhance code maintainability and understanding.
3.
No Compilation Step
TypeScript requires compilation to change the TypeScript code into JS so the engine can understand it, while JSDoc does not require any other step as they are just "comments", which is supported feature of JS itself.
# CHAPTER 2
Drawbacks of using JSDoc
Stronger Static Typing
TypeScript provides a strong model for types and catches these errors at compile time. Unlike JSDoc, where these typing end in the code itself and isn't enforced.
1.
2.
Type Inference
TypeScript can infer the type from its value. This helps reduce explicit type annotations and makes the codebase less verbose.
3.
Transpilation
TypeScript can adopt the latest and future features of the JS language with its polyfill feature. It effectively transpiles these codes down to understandable versions for browsers that would not have support for the features yet.
# CHAPTER 2
// TypeScript
function stringsStringStrings(p1: string, p2?: string, p3?: string, p4 = "test"): string {
// ...
}
// JSDoc
/**
* @param {string} p1
* @param {string=} p2
* @param {string} [p3]
* @param {string} [p4="test"]
* @return {string}
*/
function stringsStringStrings(p1, p2, p3, p4) {
// ...
}
# PRESENTING CODE
Readability
const thing = document.querySelector('#my-element')
addStuff(thing); // Error: type undefined is not assignable to type Thing
// or
const data = await fetch('https://my-url.dev');
return data.results // error: data is possibly undefined
// TypeScript
const thing = document.querySelector('#my-element')
addStuff(thing!); // although probably don't do this
addStuff(thing as Thing) // still not great but it works
// JSDoc
const thing = document.querySelector('#my-element')
addStuff(
// thing is definitely defined by this point, see line 120
// @ts-ignore-next-line
thing
);
# PRESENTING CODE
Flexibility
- Complementary Documentation
- Richer IDE Support
- Usage Examples
- Descriptive Annotations
JSDoc in TypeScript:
Enhancing Documentation
Improving DX with Better Tooling
# PRESENTING CODE
# PRESENTING CODE
- Highlight lines containing diagnostics
- Append diagnostic as text to the end of the line
- Show icons in gutter
- Show message in status bar
# PRESENTING CODE
The End :)
From JSDoc to TypeScript
By Nikita Malik
From JSDoc to TypeScript
- 148