typescript 如何迭代打字稿中的自定义文字类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40863488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to iterate over a custom literal type in typescript?
提问by k0pernikus
I have defined a custom literal type in typescript:
我在打字稿中定义了一个自定义文字类型:
export type Market = 'au'|'br'|'de';
Now I want to iterate over each possible Market
without having to create an array of Market[]
in the first place as it feelsredundant and I may forget to add one option:
现在我想迭代每一个可能的,Market
而不必首先创建一个数组,Market[]
因为它感觉多余,我可能会忘记添加一个选项:
const markets: Market[] = ['au', 'br', 'de'];
markets.forEach((market: Market) => {
console.log(market);
});
Is there a way to achieve that with typescript?
有没有办法用打字稿实现这一目标?
采纳答案by Tim Perry
No, you can't do that, as pure type information like that doesn't exist at runtime.
不,您不能这样做,因为在运行时不存在这样的纯类型信息。
It's hypothetically plausible to do the other way (define a normal list of strings, and then derive the 'au'|'br'|'de'
type from that), but I don't think the TypeScript compiler (either 2.0 or 2.1) will currently infer that for you - as far as I know the type of markets will always be string[]
normally.
以另一种方式做假设是合理的(定义一个普通的字符串列表,然后从中派生出'au'|'br'|'de'
类型),但我认为 TypeScript 编译器(2.0 或 2.1)目前不会为您推断出这一点 - 就我知道市场的类型总是string[]
正常的。
The right answer to this is to use enums. They define a type with each of their values, and it's possible to get a list of all their string values: How to programmatically enumerate an enum type in Typescript 0.9.5?.
对此的正确答案是使用枚举。他们为每个值定义了一个类型,并且可以获得所有字符串值的列表:How to programmatically enumerate an enum type in Typescript 0.9.5? .
The one downside to enums is that their runtime representation is different (under the hood they're actually numbers, not strings). Your code can still treat them as nice readable values though, it's just you'll have to translate them to strings if do you ever you need them as string names at runtime. That's easy though: given enum MarketEnum
and a value myEnumValue
, MarketEnum[myEnumValue]
is the value's name as a string).
枚举的一个缺点是它们的运行时表示不同(在引擎盖下它们实际上是数字,而不是字符串)。您的代码仍然可以将它们视为很好的可读值,只是如果您在运行时需要它们作为字符串名称,则必须将它们转换为字符串。不过这很容易:给定 enumMarketEnum
和一个 value myEnumValue
,MarketEnum[myEnumValue]
是作为字符串的值的名称)。
回答by Joseph Andaverde
Here's an alternative way:
这是另一种方法:
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
}
The underlying representation is no longer numbers it's the string.
底层表示不再是数字,而是字符串。
"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);
}
回答by Joseph Andaverde
Here's what I would do to create an array that contains all of your values at run-time and is checked at compile time:
这是我在运行时创建一个包含所有值并在编译时检查的数组的操作:
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
}
})
})()