繁体   English   中英

如何迭代 TypeScript 中的自定义文字类型?

[英]How can I iterate over a custom literal type in TypeScript?

我在 TypeScript 中定义了一个自定义文字类型:

export type Market = 'au'|'br'|'de';

现在我想遍历每个可能的Market而不必首先创建Market[]数组,因为它感觉多余,我可能会忘记添加一个选项:

const markets: Market[] = ['au', 'br', 'de'];
markets.forEach((market: Market) => {
    console.log(market);
});

有没有办法用 TypeScript 实现这一点?

对于那些使用 TypeScript >= 3.4 访问这个问题的人,我相信现在最好的做法是创建一个常量字符串数组,然后使用运算符的类型。

示例:

export const markets = ['au', 'br', 'de'] as const;
export type Market = typeof markets[number];

markets.forEach((market: Market) => {
    console.log(market);
});

不,您不能这样做,因为在运行时不存在这样的纯类型信息。

以另一种方式做假设是合理的(定义一个普通的字符串列表,然后从中派生'au'|'br'|'de'类型),但我不认为 TypeScript 编译器(2.0 或 2.1 ) 目前将为您推断出这一点 - 据我所知,市场类型通常始终为string[]

正确的答案是使用枚举。 他们为每个值定义了一个类型,并且可以获得所有字符串值的列表: How to programmatically enumerate an enum type in Typescript 0.9.5? .

枚举的一个缺点是它们的运行时表示不同(在引擎盖下它们实际上是数字,而不是字符串)。 您的代码仍然可以将它们视为很好的可读值,只是如果您在运行时需要它们作为字符串名称,则必须将它们转换为字符串。 不过这很容易:给定 enum MarketEnum和值myEnumValueMarketEnum[myEnumValue]是值的名称作为字符串)。

这是另一种方法:

enum Market {
   'eu' = 'eu',
   'us' = 'us',
}

const all_possible_market_values = getStringValuesFromEnum(Market)

function getStringValuesFromEnum<T>(myEnum: T): (keyof T)[] {
   return Object.keys(myEnum) as any
}

底层表示不再是数字。 这是字符串。

"use strict";
var Market;

(function (Market) {
    Market["eu"] = "eu";
    Market["us"] = "us";
})(Market || (Market = {}));

const all_possible_market_values = getStringValuesFromEnum(Market);

function getStringValuesFromEnum(myEnum) {
    return Object.keys(myEnum);
}

我认为最容易遵循的 TypeScript 3.9 完整示例:

enum SupportedLangugesEnum {
    'au' = 'au',
    'br' = 'br',
    'de' = 'de',
}

for (let entry in SupportedLangugesEnum) {
    if (isNaN(Number(entry))) {
        console.log(entry);
    }
}

for (let entry of Object.keys(SupportedLangugesEnum)) {
    console.log(entry);
}

for (let entry of Object.values(SupportedLangugesEnum)) {
    console.log(entry);
}

将打印:

在此处输入图片说明

来源:

https://stackoverflow.com/a/39372911/3850405

这是我在运行时创建一个包含所有值并在编译时检查的数组的操作:

export type Market = 'eu' | 'us'

export const MARKET_TYPES: Market[] = (() => {
   const markets: Market[] = ['eu', 'us']

   return markets.map((x: Market) => {
      if (x === 'eu') {
         return x
      } else if (x === 'us') {
         return x
      } else {
         const _exhaustive_check: never = x
         return _exhaustive_check
      }
   })
})()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM