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

如何在TypeScript中迭代自定义文字类型?,typescript,types,Typescript,Types,我在TypeScript中定义了一个自定义文字类型: export type Market = 'au'|'br'|'de'; 现在我想迭代每个可能的Market,而不必首先创建Market[]数组,因为它感觉多余,我可能会忘记添加一个选项: const markets: Market[] = ['au', 'br', 'de']; markets.forEach((market: Market) => { console.log(market); }); 有没有办法用Type

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

export type Market = 'au'|'br'|'de';
现在我想迭代每个可能的
Market
,而不必首先创建
Market[]
数组,因为它感觉多余,我可能会忘记添加一个选项:

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

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

不,你不能这样做,因为像这样的纯类型信息在运行时是不存在的

假设用另一种方法(定义一个正常的字符串列表,然后从中派生出
'au'|'br'|'de'
类型)是可行的,但我认为TypeScript编译器(2.0或2.1)目前不会推断出对您来说-据我所知,市场的类型通常都是
string[]

正确的答案是使用枚举。它们使用各自的值定义一个类型,并且可以获得其所有字符串值的列表:


枚举的一个缺点是它们的运行时表示形式不同(实际上它们是数字,而不是字符串)。尽管如此,您的代码仍然可以将它们视为良好的可读值,只是如果您在运行时需要它们作为字符串名,您必须将它们转换为字符串。不过这很简单:给定enum
markeenum
和一个值
myEnumValue
markeenum[myEnumValue]
是一个字符串形式的值名。)

我将创建一个数组,该数组在运行时包含所有值,并在编译时进行检查:

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
      }
   })
})()

这里有另一种方法:

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
}

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);
}
将打印:

资料来源:


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

例如:

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

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

这是不可能的,但我真的希望TS团队在类型中添加一些类似于运行时可用的内省的东西。类型别名(和接口)的全部要点是它们不会被编译成javascript。如果你只想编译一些东西,那么你可以使用它,但是如果你在运行时需要它,那么你必须使用js中存在的一些东西。谢谢:-)作为常量的
是什么意思?它告诉Typescript它是不可变的。在这种情况下,
Market
类型等于
string
(而不是
'au'|'br'|'de'
)。这不是违背了目的吗?@scale\u tone-不正确。市场类型不等于
字符串
`常量市场=['au','br','de']作为常量;市场类型=市场类型[数量];常数测试:市场=测试;类型“test”不可分配给类型“br”|“au”|“de”`@基思·哈克巴特,真的。我一定是被vscode暗示骗了。你的地图不总是返回
x
?我看不出你的地图与这张地图有什么不同:
.map((x:Market)=>x)
export const markets = ['au', 'br', 'de'] as const;
export type Market = typeof markets[number];

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