bra*_*ipt 2 javascript generics typescript typescript-generics
假设我有一个对象,我想确保它的键符合另一种类型。我正在创建映射键的字典,其中左侧是原始键,右侧是显示的键。我需要在运行时和编译时都可用它,因此将其作为const对象和数组执行似乎有意义吗?
(是的,我尝试使用元组数组执行此操作,但 TypeScript 现在对我很生气)。
\nconst allowedKeys = ["cheese_type", "jalapeno_qty", "pepperoni"] as const;\n\nconst keyMap = {\n cheese_type: "Cheese type",\n jalapeno_qty: "Number of jalape\xc3\xb1os",\n pepperoni: "Pepperoni",\n} as const;\nRun Code Online (Sandbox Code Playgroud)\n这给了我一个明确映射所有键的类型:
\nconst keyMap: {\n readonly cheese_type: "Cheese type";\n readonly jalapeno_qty: "Number of jalape\xc3\xb1os";\n readonly pepperoni: "Pepperoni";\n}\nRun Code Online (Sandbox Code Playgroud)\n(我也可以导出类型)
\nexport const Keys = typeof allowedKeys\nexport const KeyMap = typeof keyMap\nRun Code Online (Sandbox Code Playgroud)\n但我也想防止keyMap意外拼写错误或添加不应该有的键,所以我想让它符合数组allowedKeys。
但如果我这样做,我无法弄清楚如何推断或定义对象值作为只读/常量属性......
\nconst allowedKeys = ["cheese_type", "jalapeno_qty", "pepperoni"] as const;\ntype Keys = typeof allowedKeys;\n\nconst keyMap: {\n [key in Keys]: string // oh no\n} = {\n cheese_type: "Cheese type",\n jalapeno_qty: "Number of jalape\xc3\xb1os",\n pepperoni: "Pepperoni",\n} as const;\nRun Code Online (Sandbox Code Playgroud)\n有什么方法可以做到这一点,而不会让我陷入疯狂的循环,例如:
\nconst keyMap: {\n [key in Keys]: key in keyMap ? keyMap[key] : never; // haha no\n} = {\n cheese_type: "Cheese type",\n jalapeno_qty: "Number of jalape\xc3\xb1os",\n pepperoni: "Pepperoni",\n} as const;\nRun Code Online (Sandbox Code Playgroud)\n(最终,我希望能够有两组可以参考的密钥......)
\nexport type RawKey = typeof keyMap;\nexport type DisplayKey = ValueOf<typeof keyMap>;\nRun Code Online (Sandbox Code Playgroud)\n
您可以使用运算satisfies符来检查值是否与特定类型匹配,而无需将其扩展到该类型,否则会丢弃您想要的信息。
因此,只要您拥有Keys想要允许的密钥类型:
const allowedKeys = ["cheese_type", "jalapeno_qty", "pepperoni"] as const;\ntype Keys = typeof allowedKeys[number];\nRun Code Online (Sandbox Code Playgroud)\n你可以这么说吧keyMap satisfies Record<Keys, string>:
const keyMap = {\n cheese_type: "Cheese type",\n jalapeno_qty: "Number of jalape\xc3\xb1os",\n pepperoni: "Pepperoni",\n} as const satisfies Record<Keys, string>;\nRun Code Online (Sandbox Code Playgroud)\n然后keyMap仍然记住其属性的所有文字类型:
/* const keyMap: {\n readonly cheese_type: "Cheese type";\n readonly jalapeno_qty: "Number of jalape\xc3\xb1os";\n readonly pepperoni: "Pepperoni";\n} */\nRun Code Online (Sandbox Code Playgroud)\n如果你犯了错误keyMap,编译器应该捕获它们:
const extraKeyMap = {\n cheese_type: "Cheese type",\n jalapeno_qty: "Number of jalape\xc3\xb1os",\n pepperoni: "Pepperoni",\n pineapple: "\xe2\x81\x89" // error!\n} as const satisfies Record<Keys, string>;\n\nconst missingKeyMap = {\n cheese_type: "Cheese type",\n pepperoni: "Pepperoni",\n} as const satisfies Record<Keys, string>; // error!\n\nconst misspelledKeyMap = {\n cheese_type: "Cheese type",\n jalapeno_qty: "Number of jalape\xc3\xb1os",\n peppperroni: "Preppypony", // error!\n} as const satisfies Record<Keys, string>;\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
925 次 |
| 最近记录: |