我想通过声明对象中的键是两种类型的串联来锁定对象的创建。由于模糊,让我用一些代码来描绘它:
type Letter = 'A' | 'B' | 'C';
boxes: { [ID in Letter]: string }[] = ...;
现在,此代码允许一个人创建一组这样的盒子:
boxes = [{ A: 1 }]; // Correct
boxes = [{ D: 1 }]; // Incorrect
我想要实现的是做同样的事情,但是在键中包含数字。像这样:
type Letter = 'A' | 'B' | 'C';
type Digit = '0' | '1' | '2';
boxes: { [ID in (Letter + '-' + Digit)]: string }[] = ...;
然后用户可以在此处创建
boxes = { 'A-1': 1 };
是否可以?如果可以,如何?
PS:键必须是动态的,即我无法声明由所有可能的组合组成的新类型
答案 0 :(得分:2)
A-1
字符串需要在运行时评估(Letter + '-' + Digit)
。在TypeScript中无法实现此类键的类型安全。
如果需要类型安全,则不能将A-1
之类的键视为适当的方式。
答案 1 :(得分:1)
这是不可能的,不支持对字符串文字的操作。
如果您的字符串集有限(如提供的示例所示),那么最好的选择是生成所有组合(不应那么多,并且可以编写脚本来生成它们)
如果有很多可能的组合,那么仅使用简单的索引签名可能会做得更好。
另一种方法是,以索引的第二部分实际上是嵌套对象的方式重新定义数据结构,它比较冗长,但类型安全:
type Letter = 'A' | 'B' | 'C';
type Digit = '0' | '1' | '2';
type UnionOfJustOneProperty<T extends string, TAll extends string> = T extends string ? { [P in T]: string } & { [P in Exclude<TAll, T>]?: never }: never;
let boxes: { [P in Letter]: UnionOfJustOneProperty<Digit,Digit> }[] = [
{
A: { "0": "value"},
B: { "1": "value"},
C: { "0": "value", /* "1": "" */} // the commented code causes an error, we can only have one key in the object
}
];