如何在编译时声明泛型数组的类型?

时间:2018-02-17 20:07:59

标签: function typescript generics type-safety

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上述切换案例(类似于解决方案here)将在运行时执行作业,但我的IDE会抱怨最后两个返回语句。

E.g。 input instanceof Buffer[]也不起作用。

1 个答案:

答案 0 :(得分: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('');
    }
}