templates - typescript :如何表达类型被限制为几种类型之一的通用函数

标签 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 |数字'和'字符串|数'。

尝试 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;
}

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

最佳答案

您还可以像这样组合您的尝试 2 和 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);

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

关于templates - typescript :如何表达类型被限制为几种类型之一的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32357839/

相关文章:

c++ - 错误 : T does not name a type - For specialisation using strongly typed enums

c++ - STL迭代器包装器

java - 通用 Pair 类的自己的迭代器

angular - 减少从时间戳中获取/显示的数据

reactjs - 调度问题 "Argument of type '(调度 : Dispatch<T>) => Promise<void >' is not assignable to parameter of type ' T'.”

javascript - 如何检测新浏览器选项卡中的 url 更改并取回 url?

javascript - 是否有一个 JQuery 插件可以让浏览器从当前位置平滑地向下滚动到 200 像素?

c++ - 当所有类型未知时从基类重载函数

java - 如何使用泛型在方法中返回不同的类型?

java - 类型不匹配 : cannot convert from ArrayList<Data> to MyCollection