Skip to content

TypeScript and Linting

Abdulkader Safi edited this page Jul 8, 2026 · 1 revision

TypeScript and linting

The style object is typed the way React.CSSProperties is, on top of csstype. Property names autocomplete, and a typo or a bad value is a type error.

css({ backgroundColor: "#444" }); // fine, autocompletes
css({ borderColor: 42 }); // Error: number is not assignable to a color
css({ bacgroundColor: "#444" }); // Error: unknown property, the typo is caught
css({ "&:hover": { colr: "red" } }); // Error: typo caught inside nested blocks too

That is the linting for anyone using SafiCSS. No stylelint plugin for the object API. TypeScript is the linter here.

How the typing works

The old permissive type accepted any string key, so a misspelled property looked like a selector and slipped through. The current type is strict:

  • Standard CSS properties come from csstype, fully typed.
  • Nested blocks live under keys that start with & (selectors, pseudo-classes) or @ (at-rules).
  • Custom properties use -- keys.

There is no general string index, so a key that is neither a known property nor a &/@/-- key is an error. That is what turns bacgroundColor into a caught typo.

The one authoring rule

Nest descendant selectors with &:

css({
  color: "black",
  "& span": { fontWeight: 700 }, // yes
  // span: { fontWeight: 700 },   // no, this would be a type error
});

Pseudo-classes ("&:hover"), combinators ("& > a"), and at-rules ("@media ...") are unchanged.

Where you see autocomplete

You get autocomplete and errors when TypeScript is running on the file. VS Code does this for .ts and .tsx out of the box. Import from the package so the bundled saficss.d.ts types apply:

import { css } from "saficss";

In a plain .html <script> there is no type-checker, so the code runs but you do not get editor hints. If you want checking in a plain project, add a tsconfig.json and let your editor pick it up, or write your scripts as .ts and compile them.

Clone this wiki locally