我正在开发一个纯终端库,它正在用 TypeScript 重写 jQuery Terminal。
我有这个代码:
type Effect = 'g' | 'b' | 'i' | 'u' | 's' | 'o';
type NotEffect = `-${Effect}`;
type Item = '!' | '@';
type Effects = Array<Effect | NotEffect | Item>;
type Stack = Array<string>;
type Style = {[key: string]: string};
type Attrs = {[key: string]: string} & {style?: Style};
type Formating = [
Effects,
string,
string,
Array<string> | undefined,
string | undefined,
Attrs | undefined
];
const output: Formating = [[], '', '', undefined, undefined, undefined];
在格式中添加 undefined 是解决具有不同长度元素的联合类型问题的解决方法,这导致了该问题:
type Formating = [Effects, string, string]
| [Effects, string, string, Array<string>]
| [Effects, string, string, Array<string>, string]
| [Effects, string, string, Array<string>, string, Attrs]
当我想设置格式的第四个和下一个元素时,添加此类型会出错。添加 undefined 解决了 TypeScript 的问题,但它改变了 JavaScript 代码的行为。我需要添加一些技巧来解决格式具有未定义值的问题。
有没有办法用可变数量的元素格式化元组?
编辑
这是我的真实代码:
const class_i = 3; // index of the class in formatting
const attrs_i = 5; // index of attributes in formattings
function get_inherit_style(stack: Stack) {
const output: Formating = [[], '', ''];
function update_attrs(value: string) {
if (!output[attrs_i]) {
output[attrs_i] = {};
}
try {
const new_attrs = JSON.parse(value);
if (new_attrs.style) {
const new_style = new_attrs.style;
const old_style = output[attrs_i].style;
output[attrs_i] = {
...new_attrs,
...output[attrs_i],
...{
style: update_style(new_style, old_style)
}
};
} else {
output[attrs_i] = {
...new_attrs,
...output[attrs_i]
};
}
} catch (e) {
warn('Invalid JSON ' + value);
}
}
if (!stack.length) {
return output;
}
for (let i = stack.length; i--;) {
let formatting = parse_formatting(stack[i]);
if (formatting.length > 5) {
const last = formatting.slice(5).join(';');
formatting = formatting.slice(0, 5).concat(last);
}
const style = formatting[0].split(/(-?[@!gbiuso])/g).filter(Boolean);
style.forEach(function(s) {
if (is_valid_effect(s) && output[0].indexOf(s) === -1) {
output[0].push(s);
}
});
for (let j = 1; j < formatting.length; ++j) {
const value = formatting[j].trim();
if (value) {
if (j === class_i) {
if (!output[class_i]) {
output[class_i] = [];
}
const classes = value.split(/\s+/);
output[class_i] = output[class_i].concat(classes);
} else if (j === attrs_i) {
update_attrs(value);
} else if (!output[j]) {
output[j] = value;
}
}
}
}
return stringify_formatting(output);
}
我遇到一个错误:
Tuple type '[Effects, string, string]' of length '3' has no element at index '3'
访问输出[class_i]
时
最佳答案
TypeScript 支持optional elements in tuple types如果使用未标记的元组元素,则通过将 ?
添加到类型的末尾来编写:
type Formatting =
[Effects, string, string, Array<string>?, string?, Attrs?];
或者如果使用 labeled tuple elements 则到标签末尾:
type Formatting =
[a: Effects, b: string, c: string, d?: Array<string>, e?: string, f?: Attrs];
无论哪种方式都会产生允许相应元素存在或缺失的效果:
const output: Formatting = [[], '', '']; // okay
const output2: Formatting = [[], '', '', ["a"], "abc"]; // okay
关于typescript - 如何创建元组的并集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76863045/