CSE 331: comfy-tslint

comfy-tslint is a linter we use in CSE 331 that helps enforce our coding conventions. For HW3 onwards, we will use comfy-tslint as a part of the grading process. We highly suggest that students become familiar with the linter.

Using comfy-tslint

There are two ways to consume comfy-tslint.

  1. Students using Visual Studio Code can install the comfy-tslint VSCode extension, which automatically installs the linter and applies to all .ts, .tsx files.
  2. Any student can use the comfy-tslint npm package and manually run it against their code. By default, this is included in all section and homework starter code from Sec 03/HW3 onwards.

Students having trouble using comfy-tslint should reach out to course staff for support.

Rules

comfy-tslint enforces lint rules that are modeled from our coding conventions. This section lists all of its rules and a brief description.

Note that like all static analysis tools, comfy-tslint provides heuristics for our coding conventions, but does not replace abiding by them. When grading your code, we will use both your linter output and manual inspection.

Types

  • Types are required on all top-level elements (functions and variables).
  • The any type is not allowed anywhere.
  • Type casts are not allowed.

Modules

  • Only import { A, B, C } from 'file' syntax is generally allowed.
    • There are specific exceptions for react, express, assert, etc.
  • Exported elements must have JSDoc comments.

Variables

  • Array destructuring is allowed, but object destructuring is not.
  • Otherwise, only one variable should be declared at a time.

Functions

  • Functions and methods must be declared using arrow syntax.
  • Arrow functions with simple, expression bodies can be used anywhere, but those with block bodies are only for top-level functions and methods.
  • Non-arrow function expressions are only allowed in tests, e.g., as the arguments to describe and it.

Expressions

  • No ++ or -- except in the third part of a for loop.
  • No spread syntax in arrays, objects, or JSX.

Loops

  • No do or "for-in" loops.
  • Invariants are required for while and for loops but not for-of loops.
    • Invariant comments must start with Inv:
    • (The latter exception should not be abused: loops with accumulator variables should be written with "for" or "while" and should have invariants.)

Try

  • Catch variable type must be declared (which means it must be unknown).

Interfaces

  • Contain only methods, not fields.

Regular Classes

  • Cannot extend any other class.
  • Cannot be exported (only the interface is exported).
  • Fields and methods must have types.
  • Methods must be declared using arrow syntax.

Components

  • Cannot have fields.
  • Can only have render methods, life cycle methods, and event handlers.
  • Render methods must start with render
  • Event handlers must be named doXY, where X is a description of the child (e.g., SubmitButton) and Y is the event name Click, Change, Timeout, etc.
    • The list of all allowed events is: "Click", "Change", "Timeout", "Focus", "Blur", "MouseEnter", "MouseLeave", "KeyDown", "KeyUp", "KeyPress", "Fetch", "Resp", "Response", "Json", "Error"

Route Functions

  • Must be declared to take SafeRequest and SafeResponse arguments.
  • Must call res.send rather than res.json or res.text.

Fetch

  • If two arguments are used, the second one must be a record that specifies method is POST, provides a body, and sets the Content-Type to JSON.