const ProjectActions = Enum({
CLEAR: 0,
SELECT: 1,
HOVER: 1,
RENAME: 2,
});
- WIN ERGONOMIC: declarative source-code documentation of the options' arg count
- Mutually exclusively, either:
- WIN PERFORMANCE: create fast factories for 0- and 1-arg options
- LOSE DEBUGGING: truncating args for 0- and 1-arg calls
- OR
- LOSE PERFORMANCE: validate the number of args passed to the option
- WIN DEBUGGING: helpful errors when options get the wrong num of args
- OR
- LOSE SURPRISE: None of the above would be obvious behaviour from looking at Enum user code.
The surprising behaviour kills this idea, I think.
const ProjectActions = Enum({
CLEAR: [],
SELECT: ['number'],
HOVER: ['number'],
RENAME: ['number', 'string'],
});
- WIN ERGONOMIC: declarative source-code documentation of the options' arg count and type-ish
- WIN DEBUGGING: arg-count and arg-type help in error messages.
- LOSE FLEXIBILITY:
typeof
is terrible:typeof null === typeof [] === typeof new String('') == 'object'
- No catch-all possible. Special
'any'
string or similar is super-ugly.
Small wins that don't go far enough and actually limit functionality.
const ProjectActions = Enum({
CLEAR: [],
SELECT: [/*haha javascript hates me there is no valid class for a number literal*/],
HOVER: [/*la la la la*/],
RENAME: [/*Nothing for number literal*/,/*also nothing for string literal lol*/],
})
nope.
const ProjectActions = Enum({
CLEAR: [],
SELECT: [id => typeof id === 'number'], // inline validator fn
HOVER: [_.isNumber], // or any existing validator fn
RENAME: [_.isNumber, (newName => _.isString(newName) && newName.length > 2)],
});
- WIN ERGONOMIC: declarative source-code documentation of the arg counts and type validation
- WIN DEBUGGING: arg-count and which-arg-failed help in error messages.
The user code for this seems to suggest the right things, to me. I kinda like this one.
const ProjectActions = Enum({
CLEAR: {argCount: 0},
SELECT: {args: [
{validate: _.isNumber},
]},
HOVER: {argCount: 1, check: false}, // fast-constructor
RENAME: {args: [
{validate: _.isNumber},
{validate: newName => _.isString(newName) && newName.length > 2},
]},
});
...or any other of the infinite ways you could imagine to configure argument validation...