1

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;
   }
}

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

That is exactly what I was looking for. I was creating something similar but I didn't think of having a function that returned another function. With just one function, there's no way to say that one of the generic types is inferred from arguments and the other is specified in the call as you made possible

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.