首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对字符串联合中的所有值进行彻底的迭代?

对字符串联合中的所有值进行彻底的迭代?
EN

Stack Overflow用户
提问于 2019-04-15 00:25:45
回答 3查看 1.7K关注 0票数 1

我有一个这样的字符串联盟:

export type Intervals = 'total' | 'weekly' | 'biweekly' | 'monthly' | 'annually';

我希望通过遍历联合值的数组来向用户显示这些内容:

代码语言:javascript
复制
const intervals = ['total', 'weekly', 'biweekly', 'monthly', 'annually'];
intervals.forEach(...);

如何键入intervals数组以保证它具有Intervals联合的所有值?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-04-15 03:19:17

而不是从类型派生数组,而是从数组派生类型。

代码语言:javascript
复制
export const INTERVALS = ['total', 'weekly', 'biweekly', 'monthly', 'annually'] as const;

const temp = [...INTERVALS];
export type Interval = typeof temp[0];
票数 5
EN

Stack Overflow用户

发布于 2019-04-15 01:08:23

很容易确保intervals必须分配给Array<Intervals>

代码语言:javascript
复制
const intervalsMisspelled: Array<Intervals> = 
  ['weekly', 'biweekly', 'annually', 'monthly', 'totul']; // error, "totul"

但这并不能阻止你把事情抛在脑后

代码语言:javascript
复制
const intervalsMissing: Array<Intervals> = 
  ['weekly', 'biweekly', 'annually', 'monthly']; // oops, no error but missing "total"

要解决这个问题,您可以创建一个名为ensureArray()的助手函数,它接受类型参数T (对您来说是Intervals ),然后返回一个新函数,该函数接受T类型的参数列表,并为该列表推断数组类型A。如果A数组(A[number])的元素具有比T更窄的类型,那么您肯定遗漏了什么,并且应该得到一个错误。有一种方法可以做到:

代码语言:javascript
复制
const ensureArray = <T>() => <A extends T[]>(
  ...a: A & ([T] extends [A[number]] ? A : never)
): A => a;

const ensureIntervalsArray = ensureArray<Intervals>();

const intervals = ensureIntervalsArray(
  'annually', 'biweekly', 'monthly', 'total', 'weekly'); // okay

const intervalsMisspelled = ensureIntervalsArray(
  'annually', 'biweekly', 'monthly', 'totul', 'weekly'); // error, "totul"

const intervalsMissing = ensureIntervalsArray(
  'annually', 'biweekly', 'monthly', 'weekly'); // error,
// [string, string, string, string] is not assignable to never

这是可行的,尽管您在intervalsMissing上遇到的错误是相当神秘的,它说某些东西不能分配给never,而没有告诉您真正的问题是什么。由于TypeScript目前不允许我们生产自定义类型错误,所以我们只能尝试解决这个问题。

下面给出了一个更奇怪的错误消息,但它给了开发人员一个提示:

代码语言:javascript
复制
const ensureArray = <T>() => <A extends T[]>(
  ...a: A & ([T] extends [A[number]] ? A :
    { errorMessage: [Error, "You are missing", Exclude<T, A[number]>] })
): A => a;

const ensureIntervalsArray = ensureArray<Intervals>();

const intervalsMissing = ensureIntervalsArray(
  'annually', 'biweekly', 'monthly', 'weekly'); // error,
// Property 'errorMessage' is missing in type 
// '["annually", "biweekly", "monthly", "weekly"]' 
// but required in type '{ errorMessage: [Error, "You are missing", "total"]; }'

希望其中之一能满足你的需要。祝好运!

票数 4
EN

Stack Overflow用户

发布于 2019-04-15 00:44:58

我如何键入间隔数组,以保证它有所有的值间隔联合

不容易。你可以宣布它是一个元组的结合。如果你只有'total' | 'weekly',那么你可以:

代码语言:javascript
复制
const intervals: 
| ['total', 'weekly']
| ['weekly', 'total']

这里有一个排列的nPn

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55681232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档