[英]Typescript type inference and literal types
為什么 Typescript 在第一個示例中推斷類型string
,而它能夠推斷類型文字'good' | 'bad'
第二個例子中的'good' | 'bad'
?
const alwaysSomething = () => 'something' // inferred returned type: string
const moreComplicated = (mark: number) => mark >= 10 ? 'good' : 'bad' // inferred returned type: 'good' | 'bad'
操場上。 如果你 hover alwaysSomething
,它顯示它的類型是() => string
,但是如果你 hover moreComplicated
,它顯示它的類型是(mark: number) => "good" | "bad"
(mark: number) => "good" | "bad"
。
這個問題的規范答案(如果有的話)很可能在實現字面擴展算法的拉取請求中找到。 首先,我們可以看到您所看到的行為是預期的:
在沒有返回類型注釋的 function 中,如果推斷的返回類型是文字類型(但不是文字聯合類型)並且 function 沒有包含文字類型的返回類型的上下文類型,則返回類型被擴大到其擴大的文字類型。
() => 'something'
的推斷返回類型是文字"something"
,然后擴展為string
。 另一方面,推斷的返回類型為(mark: number) => mark >= 10? 'good': 'bad'
(mark: number) => mark >= 10? 'good': 'bad'
是"good" | "bad"
"good" | "bad"
,它是一種文字聯合類型,因此不會被擴展。
為什么單值文字被加寬? 作者有這樣的評論:
[Y] 你幾乎從不想要文字類型。 畢竟,為什么要寫一個承諾總是返回相同值的 function 呢? 此外,如果我們推斷一個字面量類型,這個常見的模式就會被打破:
class Base { getFoo() { return 0; // Default result is 0 } } class Derived extends Base { getFoo() { // Compute and return a number } }
如果我們為
Base.getFoo
中的返回類型推斷類型0
,那么使用實際計算數字的實現來覆蓋它將是錯誤的。 如果你真的想返回一個文字類型,你當然可以添加一個類型注釋,即getFoo(): 0 { return 0; }
getFoo(): 0 { return 0; }
。
為什么沒有擴大字面聯盟? 這是作者后來的評論:
在
return cond? 0: 1
return cond? 0: 1
推斷的返回類型將為0 | 1
0 | 1
. 我認為在這種情況下,我們應該擴大到基本原始類型根本不清楚。 畢竟,返回類型為0 | 1
0 | 1
實際上,從 function 中傳遞出有意義的信息。
所以問題是實用性之一:人們很少打算返回單個文字類型,但他們經常打算返回文字類型的聯合。 由於類型推斷總是可以被顯式類型注釋覆蓋,因此您可以處理這種啟發式給您錯誤的情況:
const alwaysSomething = (): 'something' => 'something' // inferred returned type:
const moreComplicated = (mark: number): string => mark >= 10 ? 'good' : 'bad'
好的,希望有幫助。 祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.