繁体   English   中英

Typescript“+”运算符如何与泛型和函数一起使用?

[英]How does Typescript "+" operator work with generics and functions?

我有一个函数,它需要一些值,并在它上面执行+运算符和一个2值:

function myFunction(input: number): number {
    return input + 2;
}

如果我传递一个数字,它会将这个数字添加到2

const result = myFunction(2);
console.log('Result: ', result);
// Result: 2

如果我传递一个字符串,它会将这个字符串连接到2

const result = myFunction('2');
console.log('Result: ', result);
// Result: "22"

到目前为止一切都很好。 现在我想使用泛型来捕获类型:

function myFunction<T>(input: T): T {
    return input + 2;
}

如果我想使用它来捕获参数的隐式类型,我可以这样做:

const result = myFunction(2);
console.log('Result: ', result);
// Error: `(parameter) input: T. Operator '+' cannot be applied to types 'T' and '2'.`

如您所见,TypeScript 返回有关类型和+运算符的错误,我不明白为什么。 如果我明确设置类型,则相同:

const result = myFunction<number>(2);
console.log('Result: ', result);
// Error: `(parameter) input: T. Operator '+' cannot be applied to types 'T' and '2'.`

我不明白为什么它会返回错误+ 欢迎任何帮助!

一般来说,TypeScript +运算符比 JavaScript +运算符更严格。 后者可以在类型之间进行隐式转换,并且在操作数方面更宽容。

与泛型和函数的交互

让我们以你的函数为例。 鉴于下面的myFunction ,您会收到错误,因为T可以是任何字面意思(请参阅下面的 TypeScript + 运算符部分以了解兼容类型)。

function myFunction<T>(input: T): T {
  // Operator '+' cannot be applied to types 'T' and '2'.  
  return input + 2; 
}

TypeScript 还要求您缩小联合类型的范围,例如string | number string | number通过控制流分析。

declare const t: string | number;
t + 3; // Operator '+' cannot be applied to types 'string | number' and '3'.

// this works!
if (typeof t === "string") {
  const res = t + 3; // const res: string
} else {
  const res = t + 3; // const res: number
}

不幸的是,类型缩小在扩展联合类型的泛型中效果不佳:

function myFunction<T extends string | number>(input: T): string | number {
  if (typeof input === "string") {
    return input + 3;
  } else {
    // TypeScript could not narrow here to number, we have to cast.
    const inputNumber = input as number;
    return inputNumber + 3;
  }
}

所以这将是最终版本并回答你的问题,我猜。 作为增强,一个整洁的事情是实际返回一个条件类型。 因此,当我们输入字符串时,我们想要返回字符串。 模拟number -> number 请参阅此游乐场示例。


TypeScript +运算符的可能组合

操作数的类型矩阵(空格表示编译错误;例如在“Other”和“Boolean”类型之间):

+----------+---------+----------+---------+---------+--------+
|          |  Any    | Boolean  | Number  | String  | Other  |
+----------+---------+----------+---------+---------+--------+
| Any      | Any     | Any      | Any     | String  | Any    |
| Boolean  | Any     |          |         | String  |        |
| Number   | Any     |          | Number  | String  |        |
| String   | String  | String   | String  | String  | String |
| Other    | Any     |          |         | String  |        |
+----------+---------+----------+---------+---------+--------+

规范摘录:

二进制 + 运算符要求两个操作数都是 Number 基本类型或枚举类型,或者至少一个操作数是 Any 类型或 String 基本类型。 枚举类型的操作数被视为具有基本类型 Number。 如果一个操作数是空值或未定义值,则将其视为具有另一操作数的类型。 如果两个操作数都是 Number 原始类型,则结果是 Number 原始类型。 如果一个或两个操作数是 String 原始类型,则结果是 String 原始类型。 否则,结果为 Any 类型。

有些短语似乎有点过时了。 数字枚举解析为数字,但字符串枚举被视为字符串。 使用nullundefined和 number 无论是否严格设置,都会出现编译错误,使用 string 进行连接。 操场


背景信息: Javascript +运算符

加法运算符产生数字操作数或字符串连接的总和。

有些星座,你只能在 JavaScript 中“做”:

true + 1 // 2
false + false // 0
1 + undefined // NaN
1 + null // 1; typeof(1+ null) === "number";   // :)
new Date() + new Date() // toString() is invoked for both Date objects implicitly

操场

希望,对于您的问题范围来说,这不是太多的文字!

干杯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM