I am looking to write a JavaScript class BasicType
with five fixed instances INT
, FLOAT
, STRING
, BOOL
, ANYTHING
. It should be impossible to create any additional instances.
The instances themselves should have a single enumerable, non-configurable, non-writable property called name
. Printing these instances with console.log
, which delegates to util.inspect
, should show the class name and name, for example:
> console.log(BasicType.BOOL)
BasicType { name: 'bool' }
> BasicType.BOOL.name = "zoolean"
TypeError: Cannot assign to read only property 'name' of object '#<BasicType>'
> new BasicType("int")
Error: Basic type objects cannot be constructed
I've managed to make this work! Unfortunately my code is long and verbose and repetitive:
export class BasicType {
static INT = Object.create(BasicType.prototype, {
name: { value: "int", enumerable: true },
});
static FLOAT = Object.create(BasicType.prototype, {
name: { value: "float", enumerable: true },
});
static BOOL = Object.create(BasicType.prototype, {
name: { value: "bool", enumerable: true },
});
static STRING = Object.create(BasicType.prototype, {
name: { value: "string", enumerable: true },
});
static ANYTHING = Object.create(BasicType.prototype, {
name: { value: "anything", enumerable: true },
});
constructor() {
throw new Error("Basic type objects cannot be constructed");
}
}
The feedback I am looking for is:
- Is there a way to iterate through the five values? I don't see how since I have to declare the static properties. Maybe
defineProperties
(though this works with a single object) or maybe there is a static initializer construct? - Is the throwing an error in the constructor the acceptable way to do this in JavaScript? Or is the very idea of fixing the number of instances antithetical to JavaScript?
- Is the
class
construct correct here? Maybe they should just be objects? I thought of this but then theutil.inspect
would have to be hacked to make it look like all the objects in the enclosing application (yes, it is a compiler), and doing type analysis with.constructor
also would not work without hacking. So I kind of like usingclass
here, but if there is a better way, I would love to see it.
I know this is ES2022 but Node and modern browsers already support static
and I am fine using it. Any ES2022 forms are appreciated!