【问题标题】:How can I define a type for a css color in TypeScript?如何在 TypeScript 中定义 CSS 颜色的类型?
【发布时间】:2022-04-28 09:58:33
【问题描述】:

我有以下示例代码sn-p:

type Color = string;

interface Props {
    color: Color;
    text: string;
}

function Badge(props: Props) {
    return `<div style="color:${props.color}">${props.text}</div>`;
}

var badge = Badge({
    color: '#F00',
    text: 'Danger'
});

console.log(badge);

Playground

如果颜色无效,我会尝试生成错误,如下所示:

var badge = Badge({
    color: 'rgba(100, 100, 100)',
    text: 'Danger'
});

有没有办法定义Color,以便它只允许匹配以下模式之一的字符串?

  • #FFF
  • #FFFFFF
  • rgb(5, 5, 5)
  • rgba(5, 5, 5, 1)
  • hsa(5, 5, 5)

我知道有 redwhite 这样的颜色,但如果 Color 可以接受这些颜色,这可能会让这个问题更难回答。

【问题讨论】:

  • 对于正在寻找答案的人,我在 answer 中针对另一个类似问题实施了颜色检查类型。

标签: typescript types


【解决方案1】:

有一个针对a type of string which matches a pattern(正则表达式或其他内容)的提案,但该提案尚未实现。

因此,不幸的是,从 TypeScript 2.2 开始,您所要求的内容是不可能的。

【讨论】:

  • 只是为了拖拽一下:这并非不可能......它只需要太ooooone和一些像type Color = '#100000' | '#200000' | ... | '#FFFFFF' | rgb(1, 0, 0) | rgb(2, 0, 0) | ...这样的代码;)
  • 是的,这是可能的,并且编写一个自动生成的脚本似乎不是很难以置信(毕竟,有一个脚本可以从 .css 文件生成 .d.ts 文件类型 CSS 模块)。但不知何故,我认为这不是 OP 想要的 :)。
  • @gaa 我决定这样做......它使打字稿服务器崩溃,在这里看到github.com/biw/ts-color-type
  • @biw 我会报告一个错误只是为了检查他们如何处理它?
【解决方案2】:

在一般意义上你还不能这样做,但如果你有一组明确定义的颜色,你可以使用常量和字符串文字类型:

type Color = "#FFFFFF" | "#FF0000" | "#0000FF";
const WHITE: Color = "#FFFFFF";
const RED: Color = "#FF0000";
const BLUE: Color = "#0000FF";

显然,如果您想允许任何颜色,这将是不切实际的,但实际上您可能确实希望有可重用的颜色变量。

在我的项目中,我使用脚本从我的 colors.css 文件中生成一个类似的文件,该文件定义了一堆 CSS 属性:

:root {
  --primary-red: #ff0000;
  --secondary-red: #993333;
  /* etc */
}

转换为:

export const primaryRed: Color = "#ff0000";
export const secondaryRed: Color = "#993333";
// etc
export type Color = "#ff0000" | "#993333" // | etc...

我会这样使用它:

import {primaryRed} from "./Colors.ts";

interface BadgeProps {
    color: Color;
    text: string;
}  

var badge = Badge({
    color: primaryRed,
    text: 'Danger'
});

【讨论】:

    【解决方案3】:
    type RGB = `rgb(${number}, ${number}, ${number})`;
    type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`;
    type HEX = `#${string}`;
    
    type Color = RGB | RGBA | HEX;
    

    `${...}` 符号在新 (^4.1) ts 版本上可用。

    https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html

    【讨论】:

      【解决方案4】:

      理论上可以使用联合类型,但是如果您只使用十六进制代码,您就有超过 16,000,000 种可能的组合,而 typescript(至少 4.6.3)不喜欢这种想法。

      它已经被 MS 搁置了一年多了 https://github.com/microsoft/TypeScript/issues/42790

      【讨论】:

        猜你喜欢
        • 2021-08-16
        • 2020-01-23
        • 2018-02-23
        • 2010-12-24
        • 1970-01-01
        • 2020-08-05
        • 2020-12-15
        相关资源
        最近更新 更多