如何创建一个 TypeScript 类型来验证字符串格式?例如,检查字符串是否为有效的 CSS 长度属性。

9

我有一个React项目,其中一个组件需要接收一个“height”属性。该属性用于确定组件的CSS属性(我使用Emotion库)。

例如:

render() {
  const styles = css`
    height: ${this.props.height};
  `;

  return (
    <div style={styles}>
      ...
    </div>
  );
}

我有一个高度类型,目前它是

interface Props {
  height: number | string;
}

我想创建一种类型,它不仅可以检查高度是否为字符串,还可以验证高度的单位是字符串。

例如:

10px 是一个有效的属性,因此不会出现 TypeScript 错误。

10xp 将抛出 TypeScript 错误。

是否有一种方法可以创建一种类型,检查第一部分是数字,第二部分是这些值之一?

type CssAbsoluteUnit = "cm" | "mm" | "in" | "px" | "pt" | "pc";

type CssRelativeUnit = "em" | "ex" | "ch" | "rem" | "vw" | "vh" | "vmin" | "vmax" | "%";

我希望以一种使TypeScript编译器能够抛出错误的方式完成此操作,所以仅仅使用正则表达式在渲染时进行验证并不能真正地做到这一点。


你可以使用正则表达式类型,以其中一个所需的单位值作为字符串结尾。 - Rikin
据我所知,目前没有定义这种类型的方法。虽然有一个提案,但似乎在不久的将来的版本中包含这个功能的努力并不多见。 - trixn
@Rikin 我不知道在 TypeScript 中有这样的类型。你能提供一个来源吗? - trixn
实际上我错误地输入了type,正确的应该是const regex: RegExp = /my_regex/ - Rikin
2个回答

5

这可以通过 模板字面类型 实现,尽管在什么可能会错误地被视为有效方面存在一些限制:

type Unit = '%' | 'px' | 'em' | 'vh' | 'vh'

type HeightProp = `${number}${Unit}`


const valid: WidthValue[] = ['10%', '100px', '100em', '100vh', '100vw'] // Valid
const invalid: WidthValue[] = ['10leagues', 'one-hundred-px'] // Error
const falseNegative: WidthValue[] = ['10 px', '0e1px'] // Invalid but passes

这个例子并不是穷尽所有可能,但这个概念可以扩展到覆盖更广泛的CSS属性和有效值。

2

很遗憾,这似乎是在编译器完成工作后在运行时确定的。但是,如果您事先知道要传递的值,可以创建一个接口并实现将要传入的类型的类。

像这样:

interface CssUnit {
  getValue(): string;
}

class PxUnit implements CssUnit {
  private unit: string;

  constructor(value: number) {
    this.unit = value + "px";
  }

  getValue(): string {
    return this.unit;
  }
}

那么,
interface Props {
  height: CssUnit;
}

你所需做的就是传入你已经实现的类之一。
希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接