首页 > 解决方案 > 在打字稿中验证数字和枚举的联合类型

问题描述

我正在使用 Typescript 制作一个 SSML 构建器 npm 包。

我在 typescript 中有一个函数,如下所示,它将 Prosody 对象转换为 SSML 标签。

prosody(attributes: ProsodyAttributes, word: string){

        const {rate, volume, pitch} = attributes;

        let tag = `<prosody `;

        if(rate){

            tag += `rate="${rate}"`

        }

        if(pitch){

            tag += `pitch="${pitch}"`

        }

        if(volume){

            tag += `volume="${volume}"`

        }

        tag += `>${this._escape(word)}</prosody>`;

        this._elements.push(tag);

        return this;

    }

以下是类型。速率、音高和音量可以是数字或确定值。我为他们每个人创建了一个枚举。我正在使用联合类型来满足数字和固定值的需求。

enum Rate{
    xslow = "x-slow",
    slow = "slow",
    medium = "medium",
    fast = "fast",
    xfast = "x-fast"
}

enum Pitch{
    xlow = "x-low",
    low = "low",
    medium = "medium",
    high = "high",
    xhigh = "x-high"
}

export enum Volume{
    silent = "silent",
    xsoft = "x-soft",
    soft = "soft",
    medium = "medium",
    loud = "loud",
    xloud = "x-loud"
}

interface ProsodyAttributes {
    rate?: Rate | number,
    pitch?: Pitch | number,
    volume?: Volume | number
}

验证函数输入参数的正确方法是什么?

我尝试过类似下面的代码:

if (typeof rate === "number"){

  if(rate < 20 || rate > 200){

    throw("attributes.rate is out of range")

  }

} else {

  if(!Object.values(Rate).includes(rate)){

    throw("attributes.rate is invalid");

  }

}

我有以下查询:

  1. 这是正确的方法吗?
  2. 我应该首先使用枚举吗?是不是矫枉过正?

我必须在一个非打字稿项目中使用这个项目,其中速率、音高和音量的值将从请求参数中选取?

在此处输入图像描述

我设计韵律功能的方法导致类型不兼容。我应该如何处理?

标签: typescript

解决方案


枚举由打字稿编译器发出。这意味着它们存在于运行时。因此,您应该从 javascript 或 typescript 执行以下操作:

prosody({ volume: Volume.loud })

如果你使用枚举,那就是要走的路。您需要避免传入该枚举的原始值。

而且您验证的方式似乎也很好。


另一种可能更简单的替代方法是使用字符串联合。

就像是:

const rates = ["x-slow", "slow", "medium", "fast", "x-fast"] as const
type Rate = (typeof rates)[number] // "x-slow" | "slow" | "medium" | "fast" | "x-fast"

const arg = 'slow'
console.log(rates.includes(arg)) // true

现在是数组Rate中的项目之一。rates在类型化的环境中,您仍然可以获得自动完成功能(尽管它比枚举稍差):

联合自动完成

最后,这是一个见仁见智的问题,这取决于你希望你的 API 是怎样的。


推荐阅读