# My JSDoc-TypeScript cheatsheet
JSDoc-TypeScript
: JavaScript with JSDoc that is understood by TypeScript compiler. For what is supported by TypeScript compiler or langauge server, see [JSDoc Reference](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).
JSDoc's annotation looks like: `/** your annotation here */`.
## Type annotations
The list is NOT meant to be exhaustive.
**Vol. 1** -- To annotate types
* <span class="jsdoc">`@type {type}`</span>: Declare or, when placed before a parenthesis, cast an expression to `type` (like the TS keyword `as`).
* <span class="jsdoc">`@satisfies {type}`</span>: Assert but not casting the type (like the TS keyword `satisfies`).
* Support casting to `const`!
* <span class="jsdoc">`@this {type}`</span>: Declare the type of `this` in the next function context.
* <span class="jsdoc">`@param {type} name`</span>: Declare the type of `name` as `type`. Mostly useful for annotating function parameters.
* Supports optional arguments (`[name=value]`).
* Supports arguments in nested object path (`name.prop`) -- useful when a param is destructured.
* <span class="jsdoc">`@returns {type}`</span>: Declare the return type of the function.
* <span class="jsdoc">`@extends {type}`</span>: Annotate a class to refine the super type of it. Only useful when you need to write complex types like `Set<T>`.
**Vol. 2** -- To construct types
* <span class="jsdoc">`@typedef {base} type`</span>: Declare `type` that extends `base`.
* <span class="jsdoc">`@property {type} name`</span>: further annotating its properties. Only effective when `base` is a plain `object`.
* <span class="jsdoc">`@callback type`</span>: assume `base` is a function type. Use `@param` and `@returns` to annotate the function.
* <span class="jsdoc">`@template {base} T`</span>: Declare a template argument `T` to be used in conjunction with other declarations in the same block.
* `{base}` works as if it appears in `type<T extends base>`.
* Supports multiple arguments (`T,U,...`).
* Supports default arguments (`[T=object]`).
* <span class="jsdoc">`@import { ... } from 'module'`</span>: Works like `import type` in TS.
A [new feature](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#the-jsdoc-import-tag) in TypeScript v5.5 (Finally!)
Some neat TypeScript features that cannot be easily expressed:
* `var!`: Assert some variable is not null. You need to write out the exact type to cast.
* Specifying template arguments for method invocations. If the inference is wrong, you have to write out the complete type definition and cast. For instance `Object.entries<T>`, it looks like
```js
const x = { [Math.random().toString()]: Math.random() }
// uh wait a minute; I looked up the type definition:
// entries<T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][];
// doing inferencing in my head, I should write:
const entries = /** @type {[string, number][]} */ (Object.entries(x))
```
* Interfaces. `@typedef` defines types, [not interfaces](https://goulet.dev/posts/how-to-write-ts-interfaces-in-jsdoc/). I suggest one always create a `.d.ts` file as a supplement file to store your project-wide types/namespaces/interfaces.
* The imported value having implicit `any` type. There is no way to slient the error, since there is no way to cast that variable upon importing.
* WIP...
## Suppressors
* `// @ts-nocheck`: Add at the beginning of a JS file to enable/disable checking the entire file.
* `// @ts-ignore`: Ignores any error in the following line.
* `// @ts-expect-error`: Same as before, *but* if there is no error in the next line, an error is raised instead.
## jsconfig.json
* `checkJs`
* `strict`
WIP
## `.d.ts`
`.d.ts` is notorious to get it right. Especially when you insist on pure JavaScript.
## See also
* My plugin & keymap for Sublime Text: https://github.com/andy0130tw/sublime-text-jsdoc-snippets
* I get inspired by Svelte's official repository: https://github.com/sveltejs/svelte/blob/main/packages/svelte
<script type="happy hacking :)">
<style>
:root .markdown-body.markdown-body.markdown-body .jsdoc > code {
font-family: 'Fira Mono';
font-weight: 500;
background-color: #22ccff60;
}
</style>