如何在打字稿中迭代字符串文字类型

Posted

技术标签:

【中文标题】如何在打字稿中迭代字符串文字类型【英文标题】:How to iterate a string literal type in typescript 【发布时间】:2017-08-21 09:31:53 【问题描述】:

如何在 typescript 中迭代字符串文字类型?

比如我定义了这个类型

type Name = "Bill Gates" | "Steve Jobs" | "Linus Torvalds";

我想这样迭代

for (let name of Name) 
    console.log("Possible name: " + name);

或者这在打字稿中根本不可能?

【问题讨论】:

不可能。 :( 另见:github.com/Microsoft/TypeScript/issues/3628 【参考方案1】:

AFAIK 无法将字符串联合(类型)“提升”到运行时 JS(值)。

我找到的最接近的解决方案是使用enum: example / related issue。

【讨论】:

【参考方案2】:

由于 TypeScript 只是一个编译器,因此在运行时不存在任何类型信息。这意味着不幸的是你不能遍历一个类型。

根据您要执行的操作,您可以使用枚举来存储名称索引,然后您可以在数组中检索这些索引。

【讨论】:

【参考方案3】:

从 typescript 2.4 开始,可以使用字符串类型的枚举。这些枚举很容易被迭代:

https://blogs.msdn.microsoft.com/typescript/2017/06/27/announcing-typescript-2-4/

【讨论】:

【参考方案4】:

您可以定义一个数组文字,如果标记为as const,则条目的类型将是字符串文字类型的联合,而不是按照 OP 的要求迭代(联合)字符串文字类型。

从 typescript 3.4 开始,您可以在文字表达式上定义 const 断言来标记: - 不应扩大该表达式中的文字类型(例如,不要从“hello”变为字符串) - 数组字面量变成只读元组

例如:

const names = ["Bill Gates", "Steve Jobs", "Linus Torvalds"] as const;
type Names = typeof names[number];

它可以在运行时使用并检查类型,例如:

const companies = 
    "Bill Gates" : "Microsoft",
    "Steve Jobs" : "Apple",
    "Linus Torvalds" : "Linux",
 as const;

for(const n of names) 
    console.log(n, companies[n]);

const bg : Names = 'Bill Gates';
const ms = companies[bg];

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions

https://mariusschulz.com/blog/const-assertions-in-literal-expressions-in-typescript

https://microsoft.github.io/TypeScript-New-Handbook/chapters/types-from-extraction/#indexed-access-types

【讨论】:

有用的答案,但数组不应该使用逗号而不是|吗?此外,如果您需要一种类型来定义函数签名,您仍然需要定义一个,对吧?我最终在我的代码中得到了这样的东西:export type SortDirection = 'ASC' | 'DESC' export const SortDirections = ['ASC', 'DESC'] as const 修正错字谢谢。如果您需要联合类型,可以使用 typeof 找到它,如现在所示。 太好了,谢谢!您是否有指向他们讨论 typeof names[number] 语法的文档的链接?这对我来说是新的。 如果你对数组进行切片,它会变成一个联合类型的数组:const n = [...names];,你可以从中获取typeof一个条目:type Names = typeof n[0]所以语法typeof names[number]似乎是一个简写上面的语法。我昨天在dev.to/andreasbergqvist/… 上发现了typeof names[number] 的语法 这应该是公认的答案。这是你能得到的最接近的东西,而且非常简单。枚举对我来说太冗长了【参考方案5】:

您不能使用联合类型。但是你可以用枚举来做到这一点:

enum Name 
  'Bill Gates' = 'Bill Gates',
  'Steve Jobs' = 'Steve Jobs',
  'Linus Torvalds' = 'Linus Torvalds'


for (const name of Object.keys(Name)) 
  console.log('Possible name: ' + name)

【讨论】:

以上是关于如何在打字稿中迭代字符串文字类型的主要内容,如果未能解决你的问题,请参考以下文章

字符串枚举类似于打字稿中的类型[重复]

如何在打字稿中使用可能的字符串和数字索引确定对象的类型?

打字稿中对象文字的类型安全合并

如何在打字稿中扩展字符串?

无法让嵌套类型保护与打字稿中的联合类型一起使用

在打字稿中,如何检查字符串是不是为数字