Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
465 views
in Technique[技术] by (71.8m points)

typescript - Enforcing that an array within an object literal can only contain keys of the outer object

I have the following Interface definitions.

interface IComponents {
  root: IComponent,
  [key: string]: IComponent,
}

interface IComponent {
  type: string,
  children?: Array<keyof IComponents>;
}

I want that the "children" properties accept only keys of defined Components. in the case of the "root.children"-property it should only accept root, button1 and button2:

const list: IComponents = {
  root: {
    type: 'panel',
    children: ['button1', 'button2', 'button3']
  },
  button1: {
    type: 'button'
  },
  button2: {
    type: 'button'
  },
}

But it accepts also arbitrary strings, like in the example "button3".

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

But it accepts also arbitrary strings, like in the example "button3".

Reason:

You have

interface IComponents {
  root: IComponent,
  [key: string]: IComponent,
}

so keyof IComponents resolves to 'root' | string or effectively string. You almost always never want to have well defined names and string indexers in the same group.

Solution

I would reconsider a non-cyclic design. The following:

const list: IComponents = {
  root: {
    type: 'panel',
    children: ['button1', 'button2', 'button3']
  },
  button1: {
    type: 'button'
  },
  button2: {
    type: 'button'
  },
}

The type of list depends on the assigned object. Ideally you would figure out some way that type enforces what can be assigned.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...