我想把一个字符串缩小到一个字符串的字面联合。换句话说,我想检查这个字符串是否是我的字面联合的可能值之一,这样就可以工作了(如果运算符couldbe
存在的话)。
type lit = "A" | "B" | "C";
let uni: lit;
let str = "B";
if(str couldbe lit){
uni = str;
} else {
doSomething(str);
}
如何实现这一目标?
我尝试使用if (str instanceof lit)
,但似乎不起作用。使用keyof
迭代字符串联合也不起作用,因为允许的值本身不是键。
一种方法是使用switch
,其中每个可能的值对应一个case,但是如果lit
的允许值发生变化,则可能会导致细微的错误。
4条答案
按热度按时间xnifntxz1#
如果你像我一样讨厌转换病例:
由于TypeScript3.4- constAssert,因此也可以从字符串数组^_^中生成union类型
vhipe2zx2#
您可以使用User-Defined Type Guards。
添加:
为了避免重复编辑,
class
可以同时用于编译时和运行时。现在您所要做的就是只编辑一个地方。az31mfrm3#
这是我对类型保护和关闭
strictNullChecks
的问题的看法(这是对项目的限制;如果此选项为true
,则TS将需要switch/case
上的穷尽性)。行
const _notLit: never = maybeLit;
保证当你改变lit
类型时,你也需要更新switch/case
。这种解决方案的缺点是,随着联合类型
lit
的增长,它变得非常冗长。如果可能的话,这个任务更适合
enum
,或者如果你需要一个type
,并且不介意创建底层枚举来进行检查,你可以创建类型保护,如下所示:brccelvz4#
您也可以使用zod枚举来执行此操作:
您还可以在需要时从zod模式中提取类型:
我发现这样的验证库是解析、验证和限制类型的变量/数据的最简单、最健壮的方法,否则我必须手动编写容易出错的类型保护/ predicate 。