强制对象内的对象在TypeScript中具有相同的类型

时间:2018-06-15 03:49:24

标签: typescript generics

我需要创建一个常量列表,例如

const Days = {
  YESTERDAY: -1,
  TODAY: 0,
  TOMORROW: 1,
}

我想在Days中约束所有属性的类型,也就是说,如果我添加属性BAD_DAY: true,我希望编译器抱怨。

我开始创建类似

的东西
type ObjectOf<T> = {[k: string]: T};

const Days: ObjectOf<number> = {
   A: true;
}

这确实给了我一个错误,但是,当我在Days.之后点击ctrl-space时,我没有得到类型完成。我理解这是因为我把它作为键控对象类型。

我可以像第一个示例中那样获得代码完成,或者使用第二个示例获得编译器帮助。我可以吃蛋糕吗?我想我想要的东西就像Java Enums一样,它是一个已知的同类型对象列表。

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 个答案:

答案 0 :(得分:1)

要吃蛋糕也要吃。关于const,您需要一个通用的辅助函数。辅助函数将强制执行约束,但推断传入的对象文字的真实类型:

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

或更通用的版本:

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

如果您需要类似Java枚举的内容,那么在Typescript中没有语言支持,但您可以模拟它们,请参阅this answer