A TypeSpec library can provide an $onValidate hook, which can be used to validate whether the TypeSpec program is valid according to your libraryโs rules.
On the other hand, a linter might provide optional validation. The program could be correct, but there might be room for improvements. For instance, a linter might require documentation on every type. While this isnโt necessary to represent the TypeSpec program, it could enhance the end user experience. Linters need to be explicitly enabled, whereas $onValidate will run automatically if that library is imported.
Creating a linter
You can find examples in packages/best-practices.
1. Define rules
Provide a codefix
See codefixes for more details on how codefixes work in the TypeSpec ecosystem.
In the same way you can provide a codefix on any reported diagnostic, you can pass codefixes to the reportDiagnostic function.
Things to avoid
โ Do not call program.reportDiagnostic or your library reportDiagnostic helper directly in a linter rule
Register the rules
Export a $linter variable from your library entrypoint:
When referencing a rule or ruleset (in enable, extends, disable), you must use the rule or rule set id, which is in this format: <libraryName>/<ruleName>.
Testing a linter
To test a linter rule, a rule tester is provided, allowing you to test a specific rule without enabling the others.
First, youโll want to create an instance of the rule tester using createLinterRuleTester, passing it the rule that is being tested. You can then provide different tests to check whether the rule passes or fails.
Testing linter with codefixes
The linter rule tester provides an API to easily test a codefix. This is a different approach from the standalone codefix tester, which is more targeted at testing codefixes in isolation.
This can be done by calling applyCodeFix with the fix id. It will expect a single diagnostic to be emitted with a codefix with the given id. Then, call toEqual with the expected code after the codefix is applied.