我想创建一个标志枚举,并在其上放置实例方法。由于这是不可能直接与enum
结构,我决定做以下实验:
class SelectionsMade extends Number implements Number {
constructor(value: any) {
super(value);
}
static get None(): SelectionsMade { return new SelectionsMade(0); }
static get StartDate(): SelectionsMade { return new SelectionsMade(1 << 0); }
static get StartTime(): SelectionsMade { return new SelectionsMade(1 << 1); }
static get EndDate(): SelectionsMade { return new SelectionsMade(1 << 2); }
static get EndTime(): SelectionsMade { return new SelectionsMade(1 << 3); }
static startDate(made: boolean): SelectionsMade { return made ? this.StartDate : this.None; }
static startTime(made: boolean): SelectionsMade { return made ? this.StartTime : this.None; }
static endDate(made: boolean): SelectionsMade { return made ? this.EndDate : this.None; }
static endTime(made: boolean): SelectionsMade { return made ? this.EndTime : this.None; }
inclStartDate(): boolean {
return (this.valueOf() & SelectionsMade.StartDate.valueOf()) == SelectionsMade.StartDate.valueOf();
}
inclStartTime(): boolean {
return (this.valueOf() & SelectionsMade.StartTime.valueOf()) == SelectionsMade.StartTime.valueOf();
}
inclEndDate(): boolean {
return (this.valueOf() & SelectionsMade.EndDate.valueOf()) == SelectionsMade.EndDate.valueOf();
}
inclEndTime(): boolean {
return (this.valueOf() & SelectionsMade.EndTime.valueOf()) == SelectionsMade.EndTime.valueOf();
}
removeStartDate(): SelectionsMade {
return new SelectionsMade(this.valueOf() & ~SelectionsMade.StartDate.valueOf());
}
removeStartTime(): SelectionsMade {
return new SelectionsMade(this.valueOf() & ~SelectionsMade.StartTime.valueOf());
}
removeEndDate(): SelectionsMade {
return new SelectionsMade(this.valueOf() & ~SelectionsMade.EndDate.valueOf());
}
removeEndTime(): SelectionsMade {
return new SelectionsMade(this.valueOf() & ~SelectionsMade.EndTime.valueOf());
}
}
let s = new SelectionsMade(SelectionsMade.StartDate | SelectionsMade.EndDate);
console.log(s);
是的,它是一个扩展Number
的类,有静态getter来模仿枚举值,还有一些有用的实例方法。这确实在TS playground中打印5
,尽管您必须对unknown
进行中间强制转换,因此类型检查器是沉默的。
关于这个解决方案我有三个问题:
- 如何避免警告,你需要调用
valueOf
显式TS接受类作为一个数字(解决方法是类型断言,也不太好)? - [意见]你会认为这是一个有效的数字扩展,或者你宁愿去静态的辅助功能,尽管如此?
- 有办法写修改函数吗?例如,我有
remove*
方法,创建一个新值,而不是修改它们的值,尽管后者是可取的。
如何避免警告,您需要显式调用valueOf才能使TS接受类作为数字…
你不能。您的实例是对象,而不是原始数字。您需要使用valueOf
(或一元+
或类似的)来获得底层的原始数。
…(解决方法是类型断言,也不太好)?
使用类型断言将SelectionsMade
的实例视为原语数是不正确的。它只会让TypeScript认为它是一个原始数字,而实际上它仍然是一个对象。这对涉及它的某些操作有影响(不仅仅是typeof n
将成为"object"
而不是"number"
)。
有办法写修改函数吗?例如,我有remove*方法来创建一个新值,而不是修改它们所在的值,尽管后者更可取。
。Number
实例是不可变的。没有办法改变包装实例的基础原语数。你必须创建一个新的实例。