【发布时间】:2022-01-07 01:47:18
【问题描述】:
给定一个对象
const MyObject = {
a: 'a',
b1: 'b1',
b2: 'b2',
} as const;
我想为一个只包含以字母"b" 开头的字符串值的对象创建一个类型。如何通过字符串值的内容过滤对象类型?
这是我想用typeof MyObject构造的类型:
type OnlyBs = {
b1: "b1";
b2: "b2";
}
为了获得所需的解决方案,我使用了template literal types 和infer 关键字:
type OnlyBs = {
[K in keyof typeof MyObject]: typeof MyObject[K] extends `b${infer Rest}` ? `b${Rest}` : never;
};
然而,这给了我类型
type OnlyBs = {
readonly a: never;
readonly b1: "b1";
readonly b2: "b2";
}
这接近我想要的,但不是所需的类型。因此,在这里将它与对象 MyObject2 一起使用会给我类型错误:
const MyObject2: OnlyBs = {
b1: 'b1',
b2: 'b2',
};
“类型 '{ b1: "b1"; b2: "b2"; }' 中缺少属性 'a' 但在类型 'OnlyBs' 中是必需的。(2741)"
问题是 TypeScript 要求我添加 a 属性,尽管它的类型是 never。我想不出另一种方法来实现我的目标。我觉得我已经接近了,但我无法从生成的对象类型中删除整个属性(包括它的键)。
顺便说一句:如果这样做更容易,限制对象键(而不是属性值)的解决方案也适用于我,因为在这个特定示例中,属性值等于属性键。
TypeScript Playground 我的代码示例
【问题讨论】:
-
尝试在 OnlyBs 中返回 K 而不是
b${Rest}。这样,OnlyBs 返回允许的键。然后只需使用 Pick 即可获得所需的道具