如何检查字符串是否为特定类型

4
最初的回答: 我有这个类型:
export type PermissionType = 'creator' | 'editor' | 'viewer' 

在运行时,如何检查变量userInput是否实际上是上述类型之一

提示:该问题涉及it技术。

原始答案翻译成中文为"最初的回答"。

let userInput = 'foo' //
isOfTypePermission(userInput)  // should return false or throw an error

let userInput2 = 'creator'
isOfTypePermission(userInput2) // should return true

换句话说,如何将类型 PermissionType 编译为JavaScript数组,以便我可以轻松执行 indexOf(userInput)> -1 。最初的回答:

你需要使用一个 switch 语句。 - grooveplex
你不能将PermissionType编译成JavaScript数组,但是你可以从数组中的值推断出类型。 - artem
1个回答

26
不要把它搞得过于复杂。
function isOfTypePermission (userInput: string): userInput is PermissionType {
  return ['creator', 'editor', 'viewer'].includes(userInput);
}

请参考这里,了解为什么我们不仅使用布尔返回类型,is关键字在TypeScript中是如何工作的。
如果您的PermissionType非常长,则从const值中推断类型可能是值得的。
const permissions = ['creator', 'editor', 'viewer'] as const;
type PermissionType = (typeof permissions)[number];

function isOfTypePermission (userInput: string): userInput is PermissionType {
  return (permissions as readonly string[]).includes(userInput);
}

或者甚至是一个集合

const permissions = new Set(['creator', 'editor', 'viewer'] as const);
type PermissionType = typeof permissions extends Set<infer T> ? T : never;

function isOfTypePermission (userInput: string): userInput is PermissionType {
  return (permissions as Set<string>).has(userInput);
}

这就是我喜欢代数类型的原因,我希望其他编程语言也支持它! - Dai
4
有没有通用/动态的方法,因为在这种特殊情况下,列表可能会被更新,需要记住更新它。 - Ido Bleicher
@Bleicher 这个问题是关于字符串字面量联合类型的。看起来,如果您确定该值包含在运行时动态列表中,那么您实际上无法限制类型。您仍然只知道它是一个“字符串”。 - Patrick Roberts

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