[英]Typescript: Why is it that we cannot assign default value to generic type?
以下面為例。 我不太確定錯誤消息的含義,但從邏輯上看,簽名是完全有效的。 這只是TS不支持嗎?
function _createNominalCollection<isOutputOrdered_T extends boolean>(
input: nominal_T,
processingFunc: (count: number) => number,
orderedOutput: isOutputOrdered_T = true,
)
^^^
Type 'boolean' is not assignable to type 'isOutputOrdered_T'.
'boolean' is assignable to the constraint of type 'isOutputOrdered_T', but 'isOutputOrdered_T' could be instantiated with a different subtype of constraint 'boolean'.ts(2322)
正如@VLAZ 指出的_createNominalCollection<false>()
是有問題的。 讓我們再看看這個錯誤:
“布爾”可分配給“isOutputOrdered_T”類型的約束,但“isOutputOrdered_T”可以用約束“布爾”的不同子類型實例化。ts(2322)
這意味着您將顯式<false>
類型作為通用參數傳遞, isOutputOrdered_T
現在被限制為false
但默認參數為true
,這將違反這一點。
或者換句話說, true
和false
是boolean
的子類型,而您的 function 允許 boolean 被約束到這些子類型中的所有子類型,但不會保證所有子類型的分配。
讓我提出一個替代方案。
When you have a function that returns different types based on different arguments, you should always consider if function overloads are better suited to model that instead of generics. 它們允許您以簡單的方式將 map 參數模式專門用於特定的返回類型,而根本不需要任何 generics。
例如:
// sorted version
function myFn(orderedOutput?: true): 'sorted'
// unsorted version
function myFn(orderedOutput: false): 'unsorted'
// Implementation
function myFn(orderedOutput: boolean = true): 'sorted' | 'unsorted' {
return orderedOutput ? 'sorted' : 'unsorted'
}
// Testing
const a = myFn(true) // sorted
const b = myFn(false) // unsorted
const c = myFn() // sorted
在這里,您為 function 創建兩個簽名。 第一個“排序”版本不接受任何參數或true
。 第二個“未排序”版本接受false
。 然后你有一個處理這兩種情況的實現。
您收到此錯誤的原因是因為 isOutputOrdered_T 可能是 boolean 子類型,例如type truthy = true
或type falsy = false
,而不是完整的 boolean,例如type bool = true | false
type bool = true | false
的。 例如:
function _createNominalCollection<T extends boolean>(
orderedOutput: T
) {}
type booleanSubtype = true;
_createNominalCollection<booleanSubtype>(false);
在這個例子中,編譯器會抱怨傳遞 false,因為booleanSubtype只允許 true 作為輸入:
“false”類型的參數不能分配給“true”類型的參數
如果是真實的 boolean 子類型,就像在示例中一樣,您的默認值將不是有效輸入,這就是編譯器警告您的原因。 如果您像這樣鍵入默認值,則您的示例可以在沒有編譯器警告的情況下工作:
function _createNominalCollection<T extends boolean>(
orderedOutput: T = false as T
) {}
但如前所示,這對於真實的子類型實際上並不正確,只是消除了錯誤。
您可以選擇不將默認值分配給 false - 將其保留為未定義。
function f<T extends boolean=false>(a?: T) {
return a ? 'isTrue' : 'isNotTrue'
}
我想我會質疑為什么你首先需要這個通用的。 返回類型是否會根據此標志而改變? 如果它確實改變了為什么它需要是單個 function,那么擁有 2 個不同名稱的函數不是更有意義嗎?
您收到錯誤是因為您將true
分配給orderedOutput
作為默認參數。
如果您調用_createNominalCollection(..,..,false)
約束類型參數isOutputOrdered_T
將被推斷為false
。 當然,不允許將值true
分配給false
類型的參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.