How to Configure Diagnostic Severity Levels in TSSLint Using asWarning(), asError(), and asSuggestion()
TSSLint rules configure diagnostic severity by calling asWarning(), asError(), or asSuggestion() on the Reporter object returned by ctx.report(), which mutates the underlying ts.Diagnostic.category field to control how TypeScript displays the issue.
TSSLint is a TypeScript linter that bridges TSLint-style configurations with TypeScript's native diagnostic system. Understanding how diagnostic severity levels are configured in TSSLint using the asWarning(), asError(), and asSuggestion() methods is essential for both rule authors and configuration maintainers. This guide examines the implementation in the johnsoncodehk/tsslint repository to show exactly how these severity modifiers work under the hood.
The Reporter API and Severity Modifiers
TSSLint reports problems through a Reporter object that rules receive from the report() method. This reporter exposes three fluent API methods that map directly to TypeScript's DiagnosticCategory enum values:
| Method | Effect | TypeScript Enum Value |
|---|---|---|
asWarning() |
Emits the diagnostic as a warning | ts.DiagnosticCategory.Warning (0) |
asError() |
Emits the diagnostic as an error | ts.DiagnosticCategory.Error (1) |
asSuggestion() |
Emits the diagnostic as a suggestion | ts.DiagnosticCategory.Suggestion (2) |
The implementation in packages/core/index.ts shows these methods are simple mutators that modify the category property of the underlying diagnostic object and return this to enable method chaining:
asWarning() {
error.category = ts.DiagnosticCategory.Warning;
return this;
},
asError() {
error.category = ts.DiagnosticCategory.Error;
return this;
},
asSuggestion() {
error.category = ts.DiagnosticCategory.Suggestion;
return this;
},
These methods are defined in the Reporter interface located in packages/types/index.ts, which ensures type safety for rule authors using the TSSLint API.
Mapping Configuration Strings to Severity Levels
When users provide TSLint-style configurations, they specify severity using string literals ("error", "warn", or "off"). The conversion logic in packages/config/lib/tslint.ts translates these strings into the numeric category values consumed by the reporter:
rules[ruleName] = convertRule(
ruleModule,
options,
severity === 'error'
? 1 satisfies ts.DiagnosticCategory.Error // → invokes asError()
: severity === 'warn'
? 0 satisfies ts.DiagnosticCategory.Warning // → invokes asWarning()
: 3 satisfies ts.DiagnosticCategory.Message, // fallback (Message)
);
Inside the convertRule function, the code branches based on the numeric category value to call the appropriate reporter method:
if (category === 0 satisfies ts.DiagnosticCategory.Warning) {
reporter.asWarning();
} else if (category === 1 satisfies ts.DiagnosticCategory.Error) {
reporter.asError();
} else if (category === 2 satisfies ts.DiagnosticCategory.Suggestion) {
reporter.asSuggestion();
}
The packages/config/lib/utils.ts file contains normalizeRuleSeverity, which handles the initial parsing and validation of severity strings from configuration files, ensuring only valid RuleSeverity types reach the conversion logic.
Implementing Severity Levels in Custom Rules
Rule authors can determine diagnostic severity at runtime by invoking these methods directly on the reporter object. This pattern allows dynamic severity based on code context or rule-specific logic:
const reporter = ctx.report(
failure.getFailure(),
failure.getStartPosition().getPosition(),
failure.getEndPosition().getPosition(),
).at(new Error(), Number.MAX_VALUE);
// Determine severity based on runtime conditions
if (isCriticalViolation) {
reporter.asError(); // Hard failure
} else if (requiresAttention) {
reporter.asWarning(); // Soft failure
} else {
reporter.asSuggestion(); // Optional improvement
}
Because each method returns the reporter instance, you can chain severity configuration with other reporter methods for concise, readable rule implementations.
Summary
- Severity modifiers (
asWarning(),asError(),asSuggestion()) are fluent methods on the Reporter object that set thets.Diagnostic.categoryfield. - TypeScript enum mapping: Warning (
0), Error (1), and Suggestion (2) correspond directly tots.DiagnosticCategoryvalues. - Configuration bridge: The
packages/config/lib/tslint.tsfile maps user-provided strings ("error","warn") to these numeric categories during rule conversion. - Runtime control: Rule authors can call these methods directly after
ctx.report()to set severity dynamically based on inspection logic. - Type definitions: The Reporter interface is defined in
packages/types/index.ts, while the implementation resides inpackages/core/index.ts.
Frequently Asked Questions
What are the valid diagnostic severity levels in TSSLint?
TSSLint supports three diagnostic severity levels: Warning, Error, and Suggestion. These map to TypeScript's native DiagnosticCategory enum values 0, 1, and 2 respectively. Internally, these are set via the asWarning(), asError(), and asSuggestion() methods on the Reporter object.
How do I change a rule's severity from error to warning in TSSLint?
In your TSSLint configuration file, change the severity string for the specific rule from "error" to "warn". The configuration loader in packages/config/lib/tslint.ts automatically converts "warn" to ts.DiagnosticCategory.Warning (0), which triggers reporter.asWarning() during rule execution.
What TypeScript enum value does asSuggestion() use?
The asSuggestion() method sets the diagnostic category to ts.DiagnosticCategory.Suggestion, which has the numeric value 2. This is implemented in packages/core/index.ts by assigning error.category = ts.DiagnosticCategory.Suggestion before returning the reporter instance.
Where is the Reporter interface defined in the TSSLint source code?
The Reporter interface, which declares the asWarning(), asError(), and asSuggestion() method signatures, is defined in packages/types/index.ts. The concrete implementation that mutates the diagnostic category is located in packages/core/index.ts, while configuration parsing logic resides in packages/config/lib/tslint.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →