是否可以在 Typescript(或 ESLint?)中限制字符串的格式

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

我在使用 React (CRA) 和 TypeScript 的代码库中工作。我们已经获得了带有几个 linter 和我们自己的设计系统的典型设置。

最近,我们在 JS 中使用 CSS 更新了设计系统,以允许在来自它的任何组件上使用像 width="125px" 这样的道具。我们还引入了 Sizing 和 Spacing 尺度,允许使用 width={8}(例如)。

虽然我们正在尽最大努力在公司内部分享知识,但我看到了一些代码更改,包括 width="8" 之类的更改(如果您不习惯,这确实有意义,作为 prop 的数字通常会被设置为字符串,并且您将只为实际变量和对象保留 {})。这仍然有效并在 HTML 中输出正确的值,但它取消了编辑器中的验证(width={30} 将超出我们的规模并且会通知开发人员,width="30" 是只是一个字符串,所以我们不检查它)。

所以 TLDR,我的问题是:是否可以更积极但又更聪明的方式进行类型检查。我的目标是:

现在,如果我以 width 为例,输入是使用我们自己的比例从 {1}{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 & {});

您可以使用 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