Typescript 枚举为每个枚举实例封装一个布尔值
Typescript enum encapsulating a boolean value per enum instance
在 Typescript 中,为每个枚举实例分配布尔值的惯用方法是什么?
假设我有一个用于各种错误代码的枚举。对于每个错误代码,我都有一个布尔值,说明是否必须将错误暴露给最终用户。在Java,我愿意,
enum MyError {
ERROR1(true),
ERROR2(false),
ERROR3(false);
private boolean expose;
public boolean shouldExpose() {
return expose;
}
MyError(boolean expose) {
this.expose = expose;
}
}
这里,布尔信息(错误是否必须暴露给用户)被封装在枚举本身中。
MyError myError = MyError.ERROR1;
System.out.println(myError.shouldExpose()); //true
我如何在 Typescript 中执行此操作,因为 TS 不允许在枚举中使用布尔值?我应该在这里使用 class
还是 type
?
目标是让布尔信息包含在enum/class/type中。因此,我不想创建像
这样的包装器类型
{
error: MyError
expose: boolean
}
因为它可能导致错误的 configuration/mappings(可能 MyError.ERROR1
和 expose 为假,反之亦然其他错误)。
如果您不关心枚举顺序,那么您可以利用数字枚举,例如
enum MyError {
ERROR1 = 1,
ERROR2 = 0,
ERROR3 = 0,
}
console.log(MyError.ERROR1); // 1 == true
console.log(MyError.ERROR2); // 0 == false
console.log(MyError.ERROR3); // 0 == false
console.log(Boolean(MyError.ERROR1)); // true
console.log(Boolean(MyError.ERROR2)); // false
console.log(Boolean(MyError.ERROR3)); // false
编辑:
您可以使用名称空间合并,例如
namespace MyError {
export function shouldExpose(error:MyError) {
return Boolean(error);
}
}
console.log(MyError.shouldExpose(MyError.ERROR1)); // true
您不会尝试将有关错误的信息放入枚举本身。枚举只是为了列出(好吧,枚举)错误。它们的暴露性应该保存在错误和“它暴露了吗?”的答案之间的映射中。问题。
// values don't matter; you can also skip them if you don't care for them
enum Error {
Fatal = 1,
Disk = 2,
NoInternet = 3,
}
const IS_EXPOSED: Readonly<Record<Error, boolean>> = {
[Error.Fatal]: false,
[Error.Disk]: true,
[Error.NoInternet]: true,
}
如果您错过 IS_EXPOSED
对象中的枚举,TypeScript 的类型系统将抛出错误,因此它是完全类型安全的。
您可能想放弃实际的枚举,而是创建自己的常量集。它比较冗长,但它可能会满足您的需求。
const MyError = {
error1: {
name: 'ERROR1',
expose: true
},
error2: {
name: 'ERROR2',
expose: false
},
error3: {
name: 'ERROR3',
expose: false
}
} as const;
type MyError = typeof MyError[keyof typeof MyError]
function x(err: MyError) {
console.log(err);
}
x(MyError.error1);
x({name: 'ERROR1', expose: true});
x({name: 'ERROR1', expose: false}); // EXPECTED ERROR
function getError(): MyError {
return MyError.error1;
}
var e: MyError = getError();
console.log(MyError.error1 == e); // true
console.log(MyError.error2 == e); // false
您可以创建一个 class 来扩展原生 Error
class:
enum ErrorVariant {
ERROR1 = 1,
ERROR2 = 2,
ERROR3 = 3,
}
class MyError<T extends boolean> extends Error {
constructor (
readonly variant: ErrorVariant,
private readonly expose: T,
message?: string,
) {
super(message);
}
shouldExpose (): T {
return this.expose;
}
}
const myError1 = new MyError(ErrorVariant.ERROR1, false, 'Uh oh');
myError1.shouldExpose() // false
myError1.variant // ErrorVariant => 1
const myError2 = new MyError(ErrorVariant.ERROR2, true, 'Uh oh');
myError2.shouldExpose() // true
myError2.variant // ErrorVariant => 2
myError2.message // string
为此目的使用位掩码可能是个好主意:
enum CustomErrors {
Error1 = 1 << 0,
Error2 = 1 << 1,
Error3 = 1 << 2
}
const error_1 = 0b001
const error_1_AND_2 = 0b011
const error_1_AND_3 = 0b101
const error_3 = 0b101
const isError1 = CustomErrors.Error1 & error_1 // 1, true
const isError2 = CustomErrors.Error2 & error_1 // 0, false
const isError1_2 = CustomErrors.Error2 & error_1_AND_2 // 2, true
const isError1_2_ = CustomErrors.Error3 & error_3 // 4, true
在 Typescript 中,为每个枚举实例分配布尔值的惯用方法是什么?
假设我有一个用于各种错误代码的枚举。对于每个错误代码,我都有一个布尔值,说明是否必须将错误暴露给最终用户。在Java,我愿意,
enum MyError {
ERROR1(true),
ERROR2(false),
ERROR3(false);
private boolean expose;
public boolean shouldExpose() {
return expose;
}
MyError(boolean expose) {
this.expose = expose;
}
}
这里,布尔信息(错误是否必须暴露给用户)被封装在枚举本身中。
MyError myError = MyError.ERROR1;
System.out.println(myError.shouldExpose()); //true
我如何在 Typescript 中执行此操作,因为 TS 不允许在枚举中使用布尔值?我应该在这里使用 class
还是 type
?
目标是让布尔信息包含在enum/class/type中。因此,我不想创建像
这样的包装器类型{
error: MyError
expose: boolean
}
因为它可能导致错误的 configuration/mappings(可能 MyError.ERROR1
和 expose 为假,反之亦然其他错误)。
如果您不关心枚举顺序,那么您可以利用数字枚举,例如
enum MyError {
ERROR1 = 1,
ERROR2 = 0,
ERROR3 = 0,
}
console.log(MyError.ERROR1); // 1 == true
console.log(MyError.ERROR2); // 0 == false
console.log(MyError.ERROR3); // 0 == false
console.log(Boolean(MyError.ERROR1)); // true
console.log(Boolean(MyError.ERROR2)); // false
console.log(Boolean(MyError.ERROR3)); // false
编辑:
您可以使用名称空间合并,例如
namespace MyError {
export function shouldExpose(error:MyError) {
return Boolean(error);
}
}
console.log(MyError.shouldExpose(MyError.ERROR1)); // true
您不会尝试将有关错误的信息放入枚举本身。枚举只是为了列出(好吧,枚举)错误。它们的暴露性应该保存在错误和“它暴露了吗?”的答案之间的映射中。问题。
// values don't matter; you can also skip them if you don't care for them
enum Error {
Fatal = 1,
Disk = 2,
NoInternet = 3,
}
const IS_EXPOSED: Readonly<Record<Error, boolean>> = {
[Error.Fatal]: false,
[Error.Disk]: true,
[Error.NoInternet]: true,
}
如果您错过 IS_EXPOSED
对象中的枚举,TypeScript 的类型系统将抛出错误,因此它是完全类型安全的。
您可能想放弃实际的枚举,而是创建自己的常量集。它比较冗长,但它可能会满足您的需求。
const MyError = {
error1: {
name: 'ERROR1',
expose: true
},
error2: {
name: 'ERROR2',
expose: false
},
error3: {
name: 'ERROR3',
expose: false
}
} as const;
type MyError = typeof MyError[keyof typeof MyError]
function x(err: MyError) {
console.log(err);
}
x(MyError.error1);
x({name: 'ERROR1', expose: true});
x({name: 'ERROR1', expose: false}); // EXPECTED ERROR
function getError(): MyError {
return MyError.error1;
}
var e: MyError = getError();
console.log(MyError.error1 == e); // true
console.log(MyError.error2 == e); // false
您可以创建一个 class 来扩展原生 Error
class:
enum ErrorVariant {
ERROR1 = 1,
ERROR2 = 2,
ERROR3 = 3,
}
class MyError<T extends boolean> extends Error {
constructor (
readonly variant: ErrorVariant,
private readonly expose: T,
message?: string,
) {
super(message);
}
shouldExpose (): T {
return this.expose;
}
}
const myError1 = new MyError(ErrorVariant.ERROR1, false, 'Uh oh');
myError1.shouldExpose() // false
myError1.variant // ErrorVariant => 1
const myError2 = new MyError(ErrorVariant.ERROR2, true, 'Uh oh');
myError2.shouldExpose() // true
myError2.variant // ErrorVariant => 2
myError2.message // string
为此目的使用位掩码可能是个好主意:
enum CustomErrors {
Error1 = 1 << 0,
Error2 = 1 << 1,
Error3 = 1 << 2
}
const error_1 = 0b001
const error_1_AND_2 = 0b011
const error_1_AND_3 = 0b101
const error_3 = 0b101
const isError1 = CustomErrors.Error1 & error_1 // 1, true
const isError2 = CustomErrors.Error2 & error_1 // 0, false
const isError1_2 = CustomErrors.Error2 & error_1_AND_2 // 2, true
const isError1_2_ = CustomErrors.Error3 & error_3 // 4, true