从TypeScript中强制执行对象键

时间:2019-05-23 20:25:32

标签: javascript typescript

假设我有

type Panel = 'store' | 'logs'

我想创建一个对象,该对象具有key => ReactChild,其中key仅是Panel中的值

const object = {
    store: StoreComponent,
    logs: LogsComponent
}

如何在此处定义object的类型?

4 个答案:

答案 0 :(得分:2)

我认为枚举可以满足您的要求:

enum Panel {
  Store = 'store',
  Logs = 'logs',
};

...

const object = {
  [Panel.Store]: StoreComponent,
  [Panel.Logs]: LogsComponent,
}

答案 1 :(得分:1)

提供可重复使用的键入的另一种方法可能是定义“键对类型”关系,然后构造一个联合类型PaneMap来描述Panel中每个键的值类型:

type Panel = "store" | "logs"

/*
Define reusable type relation
*/
type PanelRelation<K extends  Panel, V>  = { [key in K] : V }

/* 
Define union type describing relation of keys from Panel, to specific value types. 
This ensures that specific keys are mapped to and compatible with specific value 
types 
*/
type PanelMap = 
PanelRelation<'store', StoreComponent> & 
PanelRelation<'logs', LogsComponent>


/* Usage example */
type LogsComponent = string
type StoreComponent = number


const object:PanelMap = { 
  "store": 1,
  "logs": "x",
  // "logs": 1, <-- value type mismatch produces expected error
  // "foo": 1, <-- foo key type not in Panel produces expected error
}

答案 2 :(得分:1)

您正在寻找预定义的映射类型Record。这将采用键的并集,并创建一个对象类型,其中每个属性的类型都指定为该类型的第二个参数:

type Panel = 'store' | 'logs'

const object:Record<Panel, ReactChild> = {
    store: StoreComponent,
    logs: LogsComponent
}

答案 3 :(得分:0)

将枚举和类型组合以限制键将起作用:

enum Panel {
    store,
    logs
}

type MyObject = Partial<{ [ key in keyof typeof Panel ]: ReactChild }>

const object1: MyObject = {
    store: 2 // works
} 

const object2: MyObject = {
    whatever: 1 // invalid key
}

在我的示例中,ReactChild等于any,仅出于演示目的。