[英]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
。 請參閱此游樂場示例。
+
運算符的可能組合操作數的類型矩陣(空格表示編譯錯誤;例如在“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 類型。
有些短語似乎有點過時了。 數字枚舉解析為數字,但字符串枚舉被視為字符串。 使用null
或undefined
和 number 無論是否嚴格設置,都會出現編譯錯誤,使用 string 進行連接。 操場
+
運算符加法運算符產生數字操作數或字符串連接的總和。
有些星座,你只能在 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.