My colleague @mattcosta7 demonstrated something that feels obvious in hindsight.
Instead of enums, use a regular object. So instead of
enum State {
SOLID,
LIQUID,
GAS,
}
(playground here - note how "complex" the transpiled JavaScript becomes)
...use an object. Objects have the advantage that when the TypeScript is converted to JavaScript, it looks pretty much identical. TypeScript 5.8 makes it possible to disallow "non-erasable syntax" which means you can set up your tsconfig.json
to avoid enum
.
The alternative is an object. It's a bit more verbose but it has advantages:
const State = {
SOLID: "solid",
LIQUID: "liquid",
GAS: "gas"
} as const
type State = typeof State[keyof typeof State]
(playground here - note how simple the transpiled JavaScript is)
In the above code, if you hover the mouse over State
it'll say
'solid' | 'liquid' | 'gas'
If you had used:
type State = keyof typeof State
and then hover over the State
, you'd see:
'SOLID' | 'LIQUID' | 'GAS'
which is not what you'd expect to use.
The smart in type State = typeof State[keyof typeof State]
is that you could edit the value and the types would still all remain correct. For example:
const State = {
SOLID: "solid",
LIQUID: "liquid",
- GAS: "gas"
+ GAS: "gasy"
} as const
Alternatively, as a list of strings
You could also define the type as:
type State = 'solid' | 'liquid' | 'gas'
But then consider the code that'd use it. Instead of:
function printer(state: State) {
if (state === State.GAS) console.log("It's a gas")
else if (state === State.LIQUID) console.log("It's a liquid")
else if (state === State.SOLID) console.log("It's a solid")
else throw new Error(state)
}
printer(State.SOLID)
you have to make the JavaScript refer to these by strings exactly too:
function printer(state: State) {
if (state === 'gas') console.log("It's a gas")
else if (state === 'liquid') console.log("It's a liquid")
else if (state === 'solid') console.log("It's a solid")
else throw new Error(state)
}
printer('solid')
Simpler, but if you decide to change gas
to gasy
you have to change all the code that uses this too. E.g.
function printer(state: State) {
- if (state === 'gas') console.log("It's a gas")
+ if (state === 'gasy') console.log("It's a gas")
else if (state === 'liquid') console.log("It's a liquid")
else if (state === 'solid') console.log("It's a solid")
else throw new Error(state)
}
Comments