所以我有一个 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" | "%";
我想以打字稿编译器会抛出错误的方式执行此操作,因此仅使用正则表达式在渲染上进行验证并不能真正完成这项工作。
这可以通过模板文字类型来实现,尽管对于可能错误地传递为有效的内容存在一些限制:
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 属性和有效值。
不幸的是,这听起来像是编译器完成工作后在运行时确定的事情。但是,如果您提前知道要传递哪些值,则可以创建一个接口并为要传入的类型实现类。
类似这样的:
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;
}
您所要做的就是传入您已实现的类之一。
希望有帮助!