我有一个接受字符串的函数,它应该调用另一个只接受两个枚举值的函数。
如何将字符串类型缩小为与枚举兼容的类型?我尝试使用 object.values 但打字稿似乎不喜欢我尝试的任何方式。
export enum A {
a = "a",
b = "b",
c = "c",
}
export enum X {
x = "x",
y = "y",
z = "z",
}
export const T = { ...A, ...X } as const;
function foo(t: string): X | A {
if (Object.values(X).includes(t as X)) {
return t
}
if(Object.values(A).includes(t)){
return t
}
return X.x
}
Run Code Online (Sandbox Code Playgroud)
当然,我可以编写一个类型保护函数,但这对我来说只是作弊,因为我必须手动注意函数代码是否正确,并且它有效地正确地将字符串缩小到其中一个枚举中。所以这就是我想避免的:
function isXorA (t: string): t is X | A {
if (Object.values(X).includes(t as X)) {
return true
}
if(Object.values(A).includes(t as A)){
return true
}
return false
}
function foo(t: string): X | A {
if(isXorA(t)){
return t
}
return X.x
}
Run Code Online (Sandbox Code Playgroud)
今天在 ChatGPT 的帮助下,我编写了两个通用类型保护器,它们应该适用于任何枚举:
const isValueOfStringEnum = <T extends Record<string, string>>(enumType: T, value: string): value is T[keyof T] =>
Object.values<string>(enumType).includes(value);
Run Code Online (Sandbox Code Playgroud)
const isValueOfNumericEnum = <T extends Record<string, number | string>>(enumType: T, value: number): value is Exclude<T[keyof T], string> =>
(Object.values(enumType) as Array<number | string>).filter((v): v is number => typeof v === "number").includes(value);
Run Code Online (Sandbox Code Playgroud)
字符串和数字枚举的工作方式有点不同(反向映射),这就是数字变体有点复杂的原因。
| 归档时间: |
|
| 查看次数: |
1747 次 |
| 最近记录: |