【问题标题】:How do I assert a generic array's type at compile time?如何在编译时断言泛型数组的类型?
【发布时间】:2018-07-28 11:09:48
【问题描述】:
function concat<T extends string | Buffer>(input: T[]): T | null {
    let input0 = input[0];

    switch (typeof input0) {
        case "undefined":
            return null;

        case "string":
            return input.join("");
    }

    return Buffer.concat(input);
}

AFAIK 上面的 switch 案例(类似于解决方案 here)会在运行时完成这项工作,但我的 IDE 抱怨最后两个返回语句。

例如input instanceof Buffer[] 也不行。

【问题讨论】:

  • Buffer 定义在哪里?
  • 不,那是不是重复的。我已经阅读了那个问题,并且已经在我的代码中应用了接受的答案“使用第一个非空项目的自定义类型保护”。但仍有一个问题 - 通过here接受的答案解决。

标签: function typescript generics type-safety


【解决方案1】:

我正在使用字符串或数字数组的简化示例。顺便说一句,(string | number)[]string[] | number[] 之间存在细微差别 - 后者是相同类型元素的数组,前者是可能包含两者的数组。我已经包含了这两个示例,因为它们适合不同的用例(请注意,我正在预测其他人将来发现您的问题时可能会做什么)。

我已经简化了示例,因为我只能猜测 Buffer 的实现,并且因为简单版本遇到与原始代码完全相同的问题。

单个元素的递归处理

这个处理混合数组,即每个元素可以是字符串或数字。

此示例获取输入数组并通过依次检查每个项目将其排序为字符串和数字。

const strings: string[] =[];
const numbers: number[] = [];

function example(input: (string | number)[]) {
    const [first, ...others] = input;

    if (typeof first === 'string') {
        strings.push(first);
    } else {
        numbers.push(first);
    }

    example(others);
}

检查和断言

这个处理包含单一类型的数组,要么全是字符串,要么全是数字。

在这个例子中,我们使用类型断言告诉编译器如果第一项是字符串,那么它们都是字符串。

function example(input: string[] | number[]) {
    const first = input[0];

    if (typeof first === 'string') {
        return (<string[]>input).join('');
    } else {
        return (<number[]>input).map((n) => n.toString()).join('');
    }
}

【讨论】:

  • 该死的。我的另一个大象疏忽。 (T1 | T2)[]T1[] | T2[] 谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 2014-07-23
  • 2015-08-15
  • 1970-01-01
  • 2013-08-20
相关资源
最近更新 更多