If you look closely, you'll notice that most of your favorite NPM packages aren't written in Javascript. They're written in a fancy, new language, called "Typescript" - and for a good reason. Typescript helps you discover everything your favorite NPM packages have to offer: all of their functions, classes and interfaces. But Typescript has a steep learning curve, and your first Typescript file is the hardest to write. These snippets make it easier.
-
Stub Typescript classes with the
typescript-class
snippetWrite
typescript-class
in any.ts
file, and select the 'Typescript Class' snippet from VScode's intellisense menu. VScode will stub out an empty class, with tab stops for all of the fields that you need to fill out to customize your class. -
Stub TSdoc sections with the
class
,method
, andconst
snippetsWrite
class
in any.ts
file and select theTSdoc Class
snippet from VSCode's intellisense menu. VScode will stub out a TSdoc block with tab stops for all of the fields you need to customize to document your class. -
Add TSdoc tags to TSdoc sections with the
decorator
,deprecated
,defaultValue
,example
,param
,privateRemarks
,remarks
,returns
,see
,throws
,typeParam
andmod
snippetsWrite
decorator
,deprecated
,defaultValue
,example
,param
,privateRemarks
,remarks
,returns
,see
,throws
ortypeParam
in any TSdoc block, and vscode will add the corresponding tag to the block, along with tab stops for the tag's fields.
The best way to take advantage of Typescript is to organize your code into classes. But classes are intricate: they have static methods, private variables, private methods, instance methods, accessors and constructors. If you're new to Typescript development, it can be hard to remember these pieces when you're staring at a blank document. Lucky for you, the typescript class
clip keeps track of these pieces for you. Use it to to stub out a Typescript class. Once you do, you can focus on what your class does, rather than how it's formatted.
Once you write your typescript code, you probably want to share it with someone else. But, before you do that, you should document what it does, and why you wrote it, with TSdoc.
Typescript's first-class support for classes, interfaces, and type declarations makes it easy for programmers to independently write pieces of code that fit together. However, typescript doesn't share the context behind the code. The context includes:
- Why the code was written in the first place.
- Who the code helps, and what it helps them do.
- How the code can be used.
- How the code shouldn't be used.
TSdoc is the standard way to add context to your code. It splits your documentation into sections, each of which corresponds to a single function, variable, class or method. It further splits each section into tags. Each tag describes a different aspect of the section. Together, they give other developers a comprehensive understanding of the code you wrote. As an added bonus, TSdoc also formats your documentation into a website or markdown file, with Typedoc.
To use TSdoc, you need to write your documentation inside multi-line comments:
-
TSdoc ONLY pays attention to multi-line comments: i.e.:
/** * comment */
-
TSdoc completely ignores single-line comments: i.e.:
// comment
/* comment */
If you don't like manually typing out multi-line comments. No problem, just use the /doc
clip I've provided.
TSdoc lumps everything within a multiline comment into a single section:
/**
* This is a section
*/
/**
* This is another section
*/
To split your documentation into sections, all you need to do is make a multiline comment for each section.
But where do you put each section? TSdoc expects you to put each section directly before the piece of code it describes:
/**
* This section describes `const CoffeeBeans`
*/
const CoffeeBeans = 'French Roast';
/**
* This section describes `function grindCoffeeBeans(...)`
*/
function grindCoffeeBeans(beans: string): string {
//...
}
/**
* This section describes `class CoffeeBeanGrinder{ ... }`
*/
class CoffeeBeanGrinder {
//...
/**
* This section describes `public grind(beans:string):string
*/
public grind(beans: string): string {
//...
}
}
Every TSdoc section contains a summary, a set of blocks and a list of modifiers:
/**
* <Summary>
*
* <Block>
*
* <Block>
*
* <Block>
*
* <Modifier>
*/
The summary should contain up to three sentences that explains what the corresponding code does. E.g.:
/**
* GrindCoffeeBeans turns whole beans into powder. It can accept any kind of coffee beans, and can be adjusted to grind powder at varying levels of coarseness.
*
* <Block>
*
* <Block>
*
* <Block>
*
* <Modifier>
*/
Each block contains a single tag, followed by supporting documentation. You can even format this documentation with markdown and code fences if you want.
/**
* grindCoffeeBeans turns whole beans into powder. It can accept any kind of coffee beans, and can be adjusted to grind powder at varying levels of coarseness.
*
* @param beans - the coffee beans you want to grind
*
* @returns coffee powder
*
* @remarks
* grindCoffeeBeans actually makes use of the static method {@link CoffeeBeanGrinder.grind} under the hood.
*
* <Modifier>
*/
The list of modifiers contains tags separated by spaces, none of which are followed by text. E.g.:
/**
* grindCoffeeBeans turns whole beans into powder. It can accept any kind of coffee beans, and can be adjusted to grind powder at varying levels of coarseness.
*
* @param beans - the coffee beans you want to grind
*
* @returns coffee powder
*
* @remarks
* grindCoffeeBeans actually makes use of the static method {@link CoffeeBeanGrinder.grind} under the hood.
*
* @alpha @experimental
*/
If all of this is a lot to remember, don't worry, I've made a few clips that make it a LOT easier:
/**
* What is the class's single responsibility?
*
* @remarks
* When should you use the class? What performance benefits or other magical powers does it confer upon you?
* When shouldn't you use the class?
* What states does this class furnish?
* What behaviors does this class furnish?
* Can you inject dependencies into this class?
* Are there any situations where it makes sense to extend this class, rather than inject dependencies into it?
* How does the code in this class work?
*
* @example
* ```typescript
* // example of how to use this class here
* ```
*
* @alpha @beta @eventProperty @experimental @internal @override @packageDocumentation @public @readonly @sealed @virtual
*/
/**
* What does this method or function do?
*
* @param name - description
*
* @returnstype and meaning of return value
*
* @alpha @beta @eventProperty @experimental @internal @override @packageDocumentation @public @readonly @sealed @virtual
*/
/**
* Summary
*
* Block Tags
*
* @alpha @beta @eventProperty @experimental @internal @override @packageDocumentation @public @readonly @sealed @virtual
*/
Remember how I mentioned that every TSdoc section has a summary, blocks, and a list of modifiers? Some tags describe blocks, and others describe modifiers. But that's not all - you can actually tags within blocks. Here are all of the following tags you can use, grouped by what they describe:
Tag | Trigger | What it does: |
---|---|---|
@decorator | decorator |
Quotes an ES6 decorator expression. |
@deprecated | deprecated |
Deprecates the code it documents, and recommends an up-to-date alternative. |
@defaultValue | defaultValue |
Lists value that a property of a class or interface will have if it isn't set. |
@example | example |
Demonstrates how to use the code it documents. |
@param | param |
Describes an argument of a method or function. |
@privateRemarks | privateRemarks |
Contains documentation that should be omitted from any auto-generated documentation site. |
@remarks | remarks |
Contains an explanation of the implementation details, reasoning, or any other long-form contextual information about the code it documents. |
@returns | returns |
Describes what returns from a method or function. |
@see | see |
Lists links to other sections of the documentation or websites. |
@throws | throws |
Lists any errors that a method or function throws. |
@typeParam | typeParam |
Describes the types you can insert into the type argument of a generic function, interface or class. |
Tag | Trigger | What it does: |
---|---|---|
@inheritDoc | inheritDoc |
Copies the @remarks @params @typeParam from another section into the current section. |
@label | label |
Adds an arbitrary label to the block that contains it, so that the block can be referenced it. |
@link | link |
Links to another section, or a website. |
Note that the @mod
clip expands to: @alpha @beta @eventProperty @experimental @internal @override @packageDocumentation @public @readonly @sealed @virtual
. This includes all of the available modifier clips, each of which occupies its own tab stop. This makes it east to choose the ones you want. Keep in mind that you must place these modifiers on the LAST line of the TSdoc comment.
Tag | Trigger | What it does: |
---|---|---|
@alpha | mod |
Marks code as an 'alpha' release. |
@beta | Marks code as a 'beta' release. | |
@eventProperty | Indicates that a method returns a Browser Event or Node Event. | |
@experimental | Marks code as 'experimental' release. | |
@internal | Excludes code from a public API. | |
@override | Marks a class as overriding the class from which it inherits. | |
@packageDocumentation | Indicates that a section describes an entire package - not just the code it immediately precedes. This should only ever be used in the package's entry .d.ts file. |
|
@public | Marks code as a stable, 'public' release. This code shouldn't change. | |
@readonly | Marks a variable or property as being read-only. | |
@sealed | Indicates that a class should never be extended. | |
@virtual | Indicates that a class can not only be extended, but can also be overridden without consequence. |
When you use any of the above clips within a TSdoc section, it will automatically add in the tag name, and a placeholder for any additional text that follows the tag.
This extension contributes the snippets/snippets.code-snippets
file to VScode. When you install this extension in VScode, it grabs the snippets in this file, and offers them as intellisense suggestions when you
See CHANGELOG.md
File or Folder | What does it do? | When should you modify it? |
---|---|---|
.readme/ |
Contains all of the images used in this README. Note that everything in this folder is versioned with Git LFS. | Whenever you need to add or change the images used in this README. |
snippets/snippets.code-snippets |
Contains all of the snippets that this extension provides. | Whenever you need to change any of the snippets that this extension provides. |
.vscodeignore |
Lists the files that will not be included in this extension when its' published. | Never. |
CHANGELOG.md |
Lists the changes that each version introduces. | Whenever you increment this package's version in package.json |
package.json |
Describes the contents, scripts, and configuration details of this extension. | Whenever you need to release a new version of this package. |
README.md |
This file. | Whenever you add or change a snippet in this extension. |
See Visual Studio Code ➝ Create your own snippets
-
Open this project in VScode, then press
F5
to load the snippets in a new VScode window. -
Create a new Typescript file, or open an existing one.
-
Test the snippets you just made.
-
Whenever you save changes to the snippets, hit the 'reload' button in the debugger tray to send the changes to the VScode window.