打字稿:如何表示一个泛型函数,其中类型被限制为几种类型之一

时间:2015-09-02 15:58:24

标签: templates generics typescript

例如,如果一个方法添加两个参数a和b,它们应该是相同的类型,并且该类型应该是字符串或数字。

尝试1:

function add(a: string | number, b: string | number) { 
    return a + b; 
}

这不起作用,因为a和b的类型可能不匹配;所以产生的错误是有道理的:error TS2365: Operator '+' cannot be applied to types 'string | number' and 'string | number'.

尝试2:

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

返回相同的错误代码:error TS2365: Operator '+' cannot be applied to types 'T' and 'T'.

尝试3:

function add(a: string, b: string): string;
function add(a: number, b: number): number;
function add(a: any, b: any) {
    return a + b;
}

这个(函数重载)工作正常,但看起来有点矫枉过正。有更优雅的方式表达这个吗?

1 个答案:

答案 0 :(得分:3)

你也可以结合你的尝试2&amp; 3像这样:

function add<T extends string | number>(a: T, b: T): T;
function add(a: any, b: any) {
    return a + b;
}

然后你可以像这样使用它:

// Return type is `number`
add(1, 2);
// Return type is `string`
add('1', '2');
add<number>(1, 2);
add<string>('1', '2');

...这些导致类型错误如预期的那样:

add(1, '2');
add<number>('1', '2');
add<string>(1, 2);
add(true, false);

但是,如果您不打算使用输入类型,那么我会坚持使用函数重载。我认为最容易理解。