如何创建验证字符串格式的打字稿类型?即检查字符串是否是有效的 css 长度属性

问题描述 投票:0回答:2

所以我有一个 React 项目,其中组件采用高度支柱。该 prop 用于确定组件的 css 属性(我使用情感库)

例如,

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

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

我有一个身高类型,目前是

interface Props {
  height: number | string;
}

我不想创建一个检查高度是否为字符串的类型,而是创建一个验证高度单位(如果它是字符串)的类型。

例如,

10px
是一个有效的 prop,所以没有打字稿错误。

10xp
会抛出打字稿错误。

有没有办法创建一个类型来检查第一部分是数字,第二部分是这些值之一?

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

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

我想以打字稿编译器会抛出错误的方式执行此操作,因此仅使用正则表达式在渲染上进行验证并不能真正完成这项工作。

reactjs typescript
2个回答
6
投票

这可以通过模板文字类型来实现,尽管对于可能错误地传递为有效的内容存在一些限制:

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

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;
}

您所要做的就是传入您已实现的类之一。

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.