我正在开发一个纯终端库,它重写了打字版的jQuery终端.

我有这样的代码:

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];

将未定义添加到格式设置是一种解决方法,用于修复元素长度不同的UNION类型的问题,该问题是导致该问题的原因:

type Formating = [Effects, string, string]
  | [Effects, string, string, Array<string>]
  | [Effects, string, string, Array<string>, string]
  | [Effects, string, string, Array<string>, string, Attrs]

当我想要设置格式的第4个元素和下一个元素时,添加此类型会出错.添加未定义解决了类型脚本的问题,但它改变了Java代码的行为.我需要添加黑客来解决格式具有未定义的值的问题.

有没有一种方法可以形成一个元素数量可变的元组?

编辑

这是我真正的代码:

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);
}

我有一个错误:

长度为"%3"的元组类型"[Effects,字符串,字符串]"在索引"%3"处没有元素

当访问output[class_i]

推荐答案

如果使用未标记的元组元素,则通过在文字的任一末尾添加?来写入TypeScrip支持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

Playground link to code

Typescript相关问答推荐

React Hook中基于动态收件箱定义和断言回报类型

为什么ESLint抱怨通用对象类型?

typescript抱怨值可以是未定义的,尽管类型没有定义

访问继承接口的属性时在html中出错.角形

了解类型规则中的关键字

如何调整对象 struct 复杂的脚本函数的泛型类型?

使用Dockerfile运行Vite React应用程序时访问env变量

TypeScrip:来自先前参数的参数中的计算(computed)属性名称

将带点的对象键重新映射为具有保留值类型的嵌套对象

通过泛型函数本身推断受约束的泛型参数的类型脚本问题

Angular 自定义验证控件未获得表单值

React router 6(数据路由)使用数据重定向

我在Angular 17中的environment.ts文件中得到了一个属性端点错误

在打字应用程序中使用Zod和Reaction-Hook-Forms时显示中断打字时出错

必需的输入()参数仍然发出&没有初始值设定项&q;错误

React Context TypeScript错误:属性';firstName';在类型';iCards|iSearch';

为什么TS条件返回要求不明确的强制转换而不是精确的强制转换?

如何使用 AWS CDK 扩展默认 ALB 控制器策略?

如果父级被删除或删除,如何自动删除子级?

如何在 ngFor 循环中以Angular 正确动态渲染组件