枚举 TypeScript 字符串字面量

10

有没有办法循环遍历 TypeScript 字符串字面量的值?

type category = "foo" | "bar" | "baz" | "xyzzy"

for (c in category) {
    // ... do something with each category
}

我目前有类似以下的东西:

let cat: category = ...

switch (cat) {
    case "foo":
    default:
        process("foo")
        break

    case "bar":
        process("bar")
        break

    case "baz":
        process("baz")
        break

    case "xyzzy":
        process("xyzzy")
        break
}

但我更愿意使用类似的东西

let others: category = []
for (c in category) {      // Iterate over possible category values
    if (c !== "foo") others.push(c)
}

if (others.indexOf(cat) >= 0) {
    process(cat)
} else {
    process("foo")
}

let others: category = ["foo" , "bar" , "baz" , "xyzzy"] - Heretic Monkey
3
我正在尝试找到一种DRY的方式来将类别集中存放,而不必在“others”的定义中重复它们。 - Ralph
2个回答

15

使用TypeScript 2.1和keyof类型,可以反过来定义一个具有必要键的对象,并使用keyof获取所有键的联合类型:

let categoryKeys = {foo: '', bar: '', baz: '', xyzzy: ''}; // values do not matter

type category = keyof typeof categoryKeys;

let x: category = 'foo'; // ok
let z: category = 'z'; //  error TS2322: Type '"z"' is not assignable 
                       // to type '"foo" | "bar" | "baz" | "xyzzy"'.

console.log(Object.keys(categoryKeys)); // prints [ 'foo', 'bar', 'baz', 'xyzzy' ]

有没有可能说服编译器,让它认为 Object.keys(categoryKeys) 的类型是 category[] 而不仅仅是 string[]?我真的很想能够遍历 Object.keys(categoryKeys),并将元素用作需要 category 类型的函数的参数。 - Rikke Bendlin Gammelmark

4

这是类型声明。

type category = "foo" | "bar" | "baz" | "xyzzy"

TypeScript编译成没有类型的JavaScript。在TypeScript中,类型只是有关可能某些值(在这种情况下)的信息,而类型声明不会被编译为任何真实的运行时JavaScript对象。因此,您无法通过它进行迭代,但可以在switch结构中使用它。


1
话虽如此,编译器在编译时将某些特殊语法 (arrayof category?) 转换为字面数组 (["foo", "bar", ...]) 是技术上可行的,但目前绝对没有这样的功能。也可以认为这与 TypeScript 的原则并不真正相符。 - Roman Starkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接