Home > database >  Is it possible to limit the formatting of a string in Typescript (or ESLint?)
Is it possible to limit the formatting of a string in Typescript (or ESLint?)

Time:01-20

I'm working in a codebase using React (CRA) and TypeScript. We've got the typical settings with a few linters and our own Design System.

Recently, we updated the Design System with CSS in JS, to allow the use of props like width="125px" on any components coming from it. We also introduced a Sizing and Spacing scales, which allows to use width={8} (for example).

While we're trying our best to share the knowledge within the company, I'm seeing some code changes including changes like width="8" (it does make sense that if you're not used to it, a number as prop will usually be set as a string, and you would keep the {} only for actual variables and objects). This still works and outputs the right value in the HTML, but it takes away the validation within the editor (width={30} would be out of our scale and the dev would be notified, width="30" is just a string so we're not checking it).

So TLDR, my question is: Is it possible to type check more aggressively but also in a smart way. My goal would be to:

  • Allow: {10} "10px" "10rem" "10%" "inherit" etc.
  • Deny: "10"
  • Allow "10" on other props like line-height or font-weight (typed separately so I don't even think this needs to be changed)

Right now, if I take width for example, the typing is using our own scale going from {1} to {18}:

  export type Width<TLength = (string & {}) | 0> =
| Globals
| TLength
| "-moz-fit-content"
| "-moz-max-content"
| "-moz-min-content"
| "-webkit-fit-content"
| "-webkit-max-content"
| "auto"
| "fit-content"
| "intrinsic"
| "max-content"
| "min-content"
| "min-intrinsic"
| (string & {});

CodePudding user response:

You can use Template Literal Types (tsc >=4.1)

type Nums = 1 | 2 | 3;

type Unit = "px" | "em" | "%";
type NumWithUnit = `${number}${Unit}`

type Width = Nums | NumWithUnit | "inherit"

const passes: Width[] = [
  1, 2, 3,
  "10px",
  "1.5em",
  "50%",
  "inherit"
]

const fails: Width[] = [
  // @ts-expect-error
  4,
  // @ts-expect-error
  "10",
  // @ts-expect-error
  "x em"
]

Playground

  •  Tags:  
  • Related