英文:
Typescript - Restrict values of object keys to some possible values, but don't make them mandatory
问题
以下是翻译好的内容:
我已经定义了一些类型,如下所示:
export const ABC= {
A: 'A',
B: 'B',
C: 'C',
} as const;
export const DEF = {
D: 'D',
E: 'E',
F: 'F',
} as const;
export type AbcTypes = (typeof ABC)[keyof typeof ABC];
export type DefTypes = (typeof DEF)[keyof typeof DEF];
现在,我想创建一个对象,该对象的键只能是这些类型中存在的值,但不需要全部都有,因此我编写了以下代码:
type MyNewDictionary = {
[pKey in AbcTypes]: {
[eKey in DefTypes]: {
onClick: () => void;
onCancel: () => void;
}
}
};
// ...
const dictionary: MyNewDictionary = {
[ABC.A]: {
[DEF.D]: {
onClick: () => null,
onCancel: () => null,
}
}
};
然而,每当我尝试设置其中一些对象键时,它会报错,因为缺少其余的键:
类型:{ D: { onClick: () => void; onCancel: () => void; } } 缺少以下属性...
我尝试使用 Partial
和 keyof
,但结果都一样。
你可以在 这个工作的TypeScript播放器中 看到示例。
我应该如何编写代码,以便我只能使用在这些定义的类型中的键,但没有必要使用所有键?
<details>
<summary>英文:</summary>
I've got some types defined as:
export const ABC= {
A: 'A',
B: 'B',
C: 'C',
} as const;
export const DEF = {
D: 'D',
E: 'E',
F: 'F',
} as const;
export type AbcTypes = (typeof ABC)[keyof typeof ABC];
export type DefTypes = (typeof DEF)[keyof typeof DEF];
Now, I'd like to create an object that can have only values present in those types as keys, but it doesn't need to have them all, so I'm writing the following:
type MyNewDictionary = {
[pKey in AbcTypes]: {
[eKey in DefTypes]: {
onClick: () => void;
onCancel: () => void;
}
}
};
...
const dictionary: MyNewDictionary = {
[ABC.A]: {
[DEF.D]: {
onClick: () => null,
onCancel: () => null,
}
}
};
However, whenever I try to set some of these object keys, it complains because the rest are missing:
Type: { D: { onClick: () => void; onCancel: () => void; } } is missing the following properties from type: ...
I've tried using `Partial` and using `keyof`, with the same results.
Here you can see [a working Typescript playground][1].
**How could I write this so that I can only use keys inside those defined types, but without the obligation to have all the keys used?**
[1]: https://www.typescriptlang.org/play?#code/MYewdgzgLgBAggIQMIF4YG8BQN4C4YDkcBANNjAvgQqeUlUrQL4wCGEMokUA3Jpl2gwAIgFEAYjDRYcwqsNo5RVUYpjiq45mw6De-KAE8ADgFN4AI2AAVE6Y5oAFEbMgAZvGQBKANoBrU0N3GBdTYMQkAF0%20UJFTN1szBxhnO2CxcV8AoI9Q9IlogzsYAFlDADlTAHdhAEtgKFrwVgAnQykMch9jAGlAmFqwSxs7CEj8GRwYH1M%209sG4hNHxzqmp8CQAG3q-fEcvKQA%20GAA3EFqAEz41nA3WMGBTTb2DlGOzy%20uppnIfpj4BOAhBd6o1mm18GVKjVQU0wK12tIuhEAHRwFaTHA%20DIo4QY8hrDbbYC7FKvY5gACum02ZBuMDuDyeLyOMCpNLp31%20mH%20-H4QA
</details>
# 答案1
**得分**: 2
可能[映射修饰符](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#mapping-modifiers) 是你要找的东西。
在你的示例中,只需按照下面的方式添加两个问号:
```ts
type MyNewDictionary = {
[pKey in AbcTypes]?: {
[eKey in DefTypes]?: {
onClick: () => void;
onCancel: () => void;
}
}
};
英文:
Probably mapping modifiers is the thing you're looking for.
In your playground, just add two question marks as below:
type MyNewDictionary = {
[pKey in AbcTypes]?: {
[eKey in DefTypes]?: {
onClick: () => void;
onCancel: () => void;
}
}
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论