如何使用TS类型作为值

时间:2020-05-26 17:58:49

标签: javascript typescript validation types enums

我有一个TypeScript类型,其中有很多字符串,其定义如下:

type Regions = "" | "eu-west-1" | "eu-east-1" | "us-west-1" | "us-east-1" | "ap-southeast-1" | "ap-east-1"

然后我在我的代码中稍后通过查询字符串参数从URL获取区域。假设从URL检索到的区域是一个名为region

的变量

因此,我正在代码中进行一些验证,并且我想确保region的类型为Regions

因此,为了进行验证,我的代码说: if (region in Regions) { doStuff();}

如果Region是所有这些区域中的变量,那将起作用。

但是,因为Regions是一种类型,所以它会抛出一个错误: 'Regions' only refers to a type, but is being used as a value here

我理解为什么,但是如何使用或扩展type Regions

实现我想做的事情

我真的不想创建另一个对象或字符串数​​组,我只想使用现有的类型来进行此验证。

我确实创建了这样的枚举:

enum RegionsList {
  'eu-west-1',
  'eu-east-1',
  'us-west-1',
  'us-east-1',
  'ap-southeast-1',
  'ap-east-1'
}

,然后执行region in RegionsList,但这已经在复制我的Regions类型,并且必须有一个结合了2的更好的解决方案。任何帮助/建议都值得赞赏。

1 个答案:

答案 0 :(得分:3)

您不能从类型中创建值,但是可以从值中推断类型。这意味着您应该从某个运行时值开始,并让编译器从中推断出Regions类型。


例如,您可以创建一个有效区域名称的数组:

const Regions = ["", "eu-west-1", "eu-east-1", "us-west-1", 
  "us-east-1", "ap-southeast-1", "ap-east-1"] as const;
type Regions = typeof Regions[number];

您可以验证类型Regions与定义中的相同。然后,您可以使用数组检查字符串是否为有效的Regions(例如,当您实现user-defined type guard function时):

function checkRegion(region: string): region is Regions {
  return (Regions as readonly string[]).indexOf(region) >= 0;
}

或者,如果您想使用in,则可以创建一个对象,其键是您关心的值,而不是创建数组:

const Regions = {
  "": true,
  "eu-west-1": true,
  "eu-east-1": true,
  "us-west-1": true,
  "ap-southeast-1": true,
  "ap-east-1": true
}
type Regions = keyof typeof Regions;

同样,您可以验证Regions是正确的类型,并使用in

function checkRegion(region: string): region is Regions {
  return region in Regions;
}

可以如上所述使用enum,但是您需要注意,因为数字枚举具有reverse mapping,因此"0" in RegionsEnum是{ {1}},可能令人惊讶。如果您仍然愿意使用它,它可能看起来像这样:

true

(请注意要确保enum RegionsEnum { "", "eu-west-1", "eu-east-1", "us-west-1", "ap-southeast-1", "ap-east-1" } type Regions = keyof typeof RegionsEnum; function checkRegion(region: string): region is Regions { return (region !== (+region) + "") && region in RegionsEnum; } 不是“数字字符串”的额外代码)。


好的,希望能有所帮助;祝你好运!

Playground link to code