typescript - 打字稿>泛型>联合约束
问题描述
为什么打字稿编译器会抛出以下错误:
Operator '+' cannot be applied to types 'T' and 'T'.
,
编译时:
export const addNumbersOrCombineStrings = <T extends string | number>(
param1: T,
param2: T
): T => param1 + param2
?
解决方案
GitHub 中的相关问题是Microsoft/TypeScript#12410。Ryan Cavanaugh在评论中解决了您的特定问题:
T + T
T
仍然不允许扩展的地方string | number
——我们认为这不是一个好的用例,因为你是否得到连接或加法是不可预测的,因此人们不应该这样做。
如果您只是尝试将两种string | number
类型相加,同样的事情也会发生在您身上:
declare const x: string | number;
x + x; // error!
// Operator '+' cannot be applied to types 'string | number' and 'string | number'.
所以我猜他们是认真的,他们不想让你那样做。您总是可以根据自己的意愿弯曲编译器并使用类型断言禁用类型检查;
export const addNumbersOrCombineStrings = <T extends string | number>(
param1: T,
param2: T
): T => (param1 as any) + param2;
但是你不想这样做,特别是因为T extends string | number
会推断出一个字符串或数字文字,这不会给你你期望的行为:
const notThree = addNumbersOrCombineStrings(1, 2);
// const notThree: 1 | 2
const notHi = addNumbersOrCombineStrings("h", "i");
// const notHi: "h" | "i"
糟糕,这些结果是文字的联合。要使用泛型解决这个问题,您可能需要开始使用花哨的条件类型来扩展文字:
type SN<T extends string | number> = (T extends string ? string : never) |
(T extends number ? number : never);
export const addNumbersOrCombineStrings = <T extends string | number>(
param1: T,
param2: SN<T>
): SN<T> =>
(param1 as any) + param2;
const n = addNumbersOrCombineStrings(1, 2); // const n : number;
const s = addNumbersOrCombineStrings("h","i"); // const s: string;
// and do you even want to support this:
const sn = addNumbersOrCombineStrings(
Math.random() < 0.5 ? "a" : 1,
Math.random() < 0.5 ? "b" : 2
); // const sn: string | number;
但是那里也有边缘情况,可能(就像传入的值实际上string | number
就像sn
上面的情况一样)。我开始明白为什么他们不喜欢支持string | number
一起添加类型值。无论如何,希望这会有所帮助。祝你好运!
推荐阅读
- sass - 当页面重新加载时,Gulp watch with Livereload 重新加载,或者自己
- ansible - 使用 jinja2 的 ansible 库存组
- reactjs - 选择时 React Native TextInput 缩小,我该如何停止它?
- java - 在 Quarkus-Camel 中的任何其他类之前调用一个类
- php - 在第 22 行的 /usr/local/lib/php/pear/common.php 中打开所需的 'PEAR.php' (include_path='.:/usr/local/lib/php/pear') 失败
- r - 替换超出范围的值是指 r 中每一行的另一个数据框
- javascript - 有什么很棒的方法可以从数组中留下每个单独的元素吗?
- angularjs - 根据 ngIf 更改背景颜色
- javascript - 当onchange处理程序使用javascript检测长度为4时如何在状态文本框中自动添加连字符
- python - 如何在 Django 的数据表中创建过滤器列?