打字稿:与上一个参数的解析类型相同的通用类型

时间:2018-07-09 14:49:14

标签: typescript generics

我想知道,当类型可以是多种类型时,如何指定与上一个参数的解析类型相同的泛型类型。

TypeScript playground

function add<T extends (number | string)>(a: T, b: T): T {
    if (typeof a === 'string') {
        return a + b;
    } else if (typeof a === 'number') {
        return a + b;
    }
}

add('hello', ' world');
add(1, 1);

我希望能够告诉编译器所有T都是相同的类型,无论是数字还是字符串。我可能会错过一些语法。条件类型(在某种程度上)可能是可能的...

1 个答案:

答案 0 :(得分:1)

您不能在函数内缩小通用参数的类型。因此,当您测试a时,不会告诉编译器b的类型是什么。更重要的是,它不会告诉编译器该函数的返回类型是什么

function add<T extends (number | string)>(a: T, b: T): T {
    if (typeof a === 'string' && typeof b === 'string') {
        let result = a + b; // result is string, we can apply + 
        return result as T; // still an error without the assertion, string is not T 
    } else if (typeof a === 'number' && typeof b === 'number') {
        let result = a + b; // result is number, we can apply +
        return result as T; // still an error without the assertion, number is not T  
    }
    throw "Unsupported parameter type combination"; // default case should not be reached
}

在这种情况下,尽管也许有一个专用的实现签名可以在联合上起作用(这意味着不需要声明),而公共签名是您先前使用的签名。:

function add<T extends number | string>(a: T, b: T): T
function add(a: number | string, b: number | string): number | string {
    if (typeof a === 'string' && typeof b === 'string') {
        return a + b;
    } else if (typeof a === 'number' && typeof b === 'number') {
        return a + b;
    }
    throw "Unsupported parameter type combination"; // default case should not be reached
}