【问题标题】:"Functional" const enum in TypeScriptTypeScript 中的“功能”常量枚举
【发布时间】:2019-11-22 16:02:06
【问题描述】:

我正在研究 React 应用程序的配色方案(使用 CSS-in-JSTS),为了方便起见,我使用 HSL 编写颜色,但是,因为它们是很多,我想以十六进制形式将它们交付给用户,以节省一些不必要的字节。我现在面临两个选择:

  • 要么我做这样的事情:
const hsl = (h: number, s: number, l: number) => {
  /* convert to hex */
  return hex;
}

const colors = {
  primary: hsl(205, 1, 0.52)
}

但是这种方法会 (1) 违背我保存字节的观点,并且 (2) 每次都需要重新计算颜色,

  • 或者我只是在其他地方写下 HSL 值,然后将十六进制代码放入我的代码中。

我发现最接近我想要做的事情是 TypeScript 的 const enums,它在编译时替换值。但是,它们只存储预定义的值,据我所知,它们不能用作函数。所以,我需要能够做这样的事情:

const enum Hsl (h: number, s: number, l: number) {
  /* convert to hex */
  return hex;
}

const colors = {
  primary: Hsl(205, 1, 0.52)
}

会被编译成

const colors = {
  primary: '#0C9BFF'
};

我怎样才能做到这一点?

ᶦˢ ᵗʰᶦˢ ᵉᵛᵉⁿ ᵖᵒˢˢᶦᵇˡᵉˀ

我考虑的另一种方法是使用第一种方法,然后让 Prepack 等工具进行一些优化(预先评估函数并删除它)。

【问题讨论】:

  • 你想“节省字节”?如果您的结论是您需要优化 HSL 功能,那么我敢打赌这是一个非常过早优化的案例。您是否有理由相信您的 HSL 功能是一个瓶颈?
  • @SilvioMayolo 他的意思是,如果该值不是一个常量(而是一个函数调用),那么 react 中的渲染函数就不能正确地确定依赖关系没有改变。我怀疑这是他们的误解,而不是过早优化的情况(因为您确实可以使用反应挂钩来记忆函数调用计算)。至于“节省字节”,它们意味着在缩小的捆绑输出中,因为十六进制字符串比 hsl 字符串短。
  • Damiano,听起来您想编写一个在prebuild 期间调用的 npm 脚本,该脚本在一个文件中获取一些 HSL 字符串并生成另一个具有等效十六进制字符串的文件,然后只需编写应用程序导入十六进制字符串,因此 HSL 字符串不会包含在输出包中,也不需要在运行时计算。这个解决方案比尝试让 TypeScript 为你做这件事更可取,因为我认为这是不可能的。
  • 嗯……我相信我会选择 Prepack,然后(它会评估部分代码并删除未使用的函数)

标签: typescript function enums constants compile-time


【解决方案1】:

你需要的是某种形式的缓存机制。

您首先根据输入生成一个唯一的 id,例如

function getId(h: number, s: number, l: number) {
   return String(h) + ',' + String(s) + ',' + String(l)
}

然后随时缓存该值:

const cache: Record<string, string> = {}
function hsl(h: number, s: number, l: number) {
  const id = getId(h, s, l)
  return cache[id] = /* do your calculation */
}

这样,当您填写预定义的colors 时,该值将被缓存,您无需重新计算。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-17
    • 2011-07-09
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    相关资源
    最近更新 更多