简体   繁体   English

打字稿:强制执行现有的对象键

[英]typescript: enforcing existing object keys

I would like dropdownAttributes to limited to attributes on DropDownItem interface.我希望dropdownAttributes仅限于DropDownItem接口上的属性。

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

if DropDownItem did now have dynamic properties I think I could solve this with keyof like this:如果DropDownItem现在确实有动态属性,我想我可以用这样的keyof解决这个问题:

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

But that does not work now in my case.但这在我的情况下现在不起作用。 How to solve?怎么解决?

You can't provide a keyof if the keys are defined in the interface as [key: string]: value , because that means, there can be virtually any key.如果键在接口中定义为[key: string]: value ,则不能提供keyof ,因为这意味着几乎可以有任何键。

Hence also, this keyof DropDownItem code returns string | number因此,这个keyof DropDownItem代码返回string | number string | number , because those are the values that the key can have. string | number ,因为这些是key可以具有的值。

在此处输入图片说明

You can avoid this by defining specific keys for the object interface:您可以通过为对象接口定义特定键来避免这种情况:

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

interface Props {
   dropdownList: DropdownItem[],
   dropdownAttributes: (keyof DropdownItem)[] // ("id" | "text" | "isDisplayed")[]
}

It seems like you want Props to be generic so that it can be used by different object types.似乎您希望Props是通用的,以便它可以被不同的对象类型使用。 This can be achieved by defining a generic type T in Props这可以通过在Props定义一个泛型类型T来实现

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

Now, if we know the types of a certain object in advance, we can create an interface for that, and create a type that uses that interface in Prop现在,如果我们事先知道某个对象的类型,我们可以为它创建一个接口,并在Prop创建一个使用该接口的类型

interface MyDropDownItem {
  foo : number
}

type MyDropDownItemProps = Props<MyDropDownItem>;

We can now only use instances of MyDropDownItem in dropdownList and its keys in dropdownAttributes现在,我们只能用实例MyDropDownItemdropdownList ,并在其键dropdownAttributes

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

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

This of course assumes you know the structure of your dropdowns in advance, because that's the only thing typescript can help you with.这当然假设您事先知道下拉列表的结构,因为这是 typescript 唯一可以帮助您的事情。 Typescript won't help you with runtime type safety. Typescript 不会帮助您解决运行时类型安全问题。

Check it out on stackblitz在stackblitz上查看

In the end I did this.最后我做到了。

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

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

export default MyComponent;

Usage:用法:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM