машинопись: применение существующих ключей объекта - PullRequest
1 голос
/ 15 февраля 2020

Я бы хотел, чтобы dropdownAttributes ограничивалось атрибутами на DropDownItem интерфейсе.

interface DropDownItem {
    [key: string]: any;
}
interface Props {
   dropdownList: DropDownItem[];
   dropdownAttributes: string[];
}

если бы DropDownItem теперь имел свойства динамичности c Я думаю, я мог бы решить эту проблему с помощью keyof следующим образом:

interface Props {
   dropdownList: DropDownItem[];
   dropdownAttributes: (keyof DropDownItem)[];
}

Но это не так работать сейчас в моем случае. Как решить?

Ответы [ 3 ]

2 голосов
/ 15 февраля 2020

Вы не можете предоставить keyof, если ключи определены в интерфейсе как [key: string]: value, потому что это означает, что может быть практически любой ключ.

Следовательно, также этот код keyof DropDownItem возвращает string | number, потому что это те значения, которые может иметь key.

enter image description here

Этого можно избежать, определив определенные c ключи для интерфейса объекта:

interface DropdownItem {
   id: number,
   text: string,
   isDisplayed: boolean,
}

interface Props {
   dropdownList: DropdownItem[],
   dropdownAttributes: (keyof DropdownItem)[] // ("id" | "text" | "isDisplayed")[]
}
1 голос
/ 15 февраля 2020

В конце концов я сделал это.

interface Props<T> {
   dropdownList: T[];
   dropdownAttributes: (keyof T)[];
}

declare class MyComponent<T> extends React.Component<Props<T>> {}

export default MyComponent;

Использование:

interface DropdownItem {
   key1: string;
   key2: string;
}

<MyComponent
   <DropdownItem>
   dropdownAttributes={['key1', 'key2']}
   dropdownList={[{key1: 'hello', key2: 'world'}]}       
/>

1 голос
/ 15 февраля 2020

Кажется, вы хотите, чтобы Props было обобщенным c, чтобы его можно было использовать различными типами объектов. Это может быть достигнуто путем определения универсального c типа T в Props

interface Props<T> {
   dropdownList: T[];
   dropdownAttributes: (keyof T)[];
}

Теперь, если мы заранее знаем типы определенного объекта, мы можем создать интерфейс для этого, и создайте тип, который использует этот интерфейс в Prop

interface MyDropDownItem {
  foo : number
}

type MyDropDownItemProps = Props<MyDropDownItem>;

Теперь мы можем использовать только экземпляры MyDropDownItem в dropdownList и его ключи в dropdownAttributes

const good: MyDropDownItemProps = {
  dropdownList: [{foo: 2}],
  dropdownAttributes : ['foo']
}

const bad: MyDropDownItemProps = {
  dropdownList: [{foo: 2, bar: 's' /* error here */}],
  dropdownAttributes : ['foo', 'bar' /* and here */ ]
}

Это, конечно, предполагает, что вы заранее знаете структуру своих выпадающих меню, потому что это единственное, что может помочь машинопись. Typescript не поможет вам с безопасностью типов во время выполнения.

Проверьте это на стеке

...