[英]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
现在,我们只能用实例
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 */ ]
}
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 不会帮助您解决运行时类型安全问题。
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.