I am modeling an API request format in TypeScript:
interface ApiTerm {
term: {
name: string,
value: string,
}
}
interface ApiAnd {
and: {
lhs: ApiItem,
rhs: ApiItem,
}
}
interface ApiOr {
or: {
lhs: ApiItem,
rhs: ApiItem,
}
}
type ApiItem =
| ApiTerm
| ApiAnd
| ApiOr
;
This works, but I will need to implement many binary operations beyond just "and" and "or" so I'd like some way to shorten and reuse the code.
Following some other code I've written that uses a specific string enum value in an interface, I tried to use a string enum as the property name:
enum Operation {
And = "and",
Or = "or",
}
interface ApiBinary<O extends Operation> {
[O]: {
lhs: ApiItem,
rhs: ApiItem,
}
}
type ApiItem =
| ApiTerm
| ApiBinary<Operation.And>
| ApiBinary<Operation.Or>
;
Unfortunately, this generates an error with TypeScript 2.9.1:
A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.
Is there an alternative solution that will allow me to avoid having to write out the numerous duplicate interfaces that will only differ by the name of the key?
Looking into the "a 'unique symbol' type" part of the error message, I don't believe I can create an enum based on Symbol
s.
Related questions
Use string enum value in TypeScript interface as a computed property key seems very close, but is about using specific string enum values in an interface, which works as-in in newer TypeScript versions.