Reputation: 92274
I need to create a list of constants, e.g.,
const Days = {
YESTERDAY: -1,
TODAY: 0,
TOMORROW: 1,
}
I would like a way to constrain the types of all properties in Days
, that is, if I add a property BAD_DAY: true
, I would like the compiler to complain.
I started by creating something like
type ObjectOf<T> = {[k: string]: T};
const Days: ObjectOf<number> = {
A: true;
}
Which does give me an error, however, I don't get type completion when I hit ctrl-space after Days.
. I understand it's because I made it a keyed object type.
I can either get code completion as in the first example, or compiler help with the second example. Can I have my cake and eat it too? I guess I want something that behaves like Java Enums in the sense that it's a known list of objects of the same type.
enum Days{
Today("SUN"), MONDAY("MON"), TUESDAY("TUES"), WEDNESDAY("WED"),
THURSDAY("THURS"), FRIDAY("FRI"), SATURDAY("SAT");
private String abbreviation;
public String getAbbreviation() {
return this.abbreviation;
}
Days(String abbreviation) {
this.abbreviation = abbreviation;
}
}
Upvotes: 1
Views: 159
Reputation: 249536
To have your cake and eat it too. With regard to the const
you need a generic helper function. The helper function will enforce the constraint, but infer the true type of the passed in object literal:
type ObjectOf<T> = {[k: string]: T};
function createObjectOfNumber<T extends ObjectOf<number>>(v:T){
return v;
}
const Days = createObjectOfNumber({
A: 1
// B: true // would be an error
});
Days.A // ok
Or a more generic version:
function createObjectOf<TValue>(){
return function<T extends ObjectOf<TValue>>(v:T){
return v;
}
}
const Days = createObjectOf<number>()({
A: 1
// B: true // would be an error
});
Days.A // ok
If you want something like Java enums, there is no language support for that in Typescript, but you can simulate them, see this answer
Upvotes: 1