簡體   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