標題中的問題幾乎說明了一切。問題是T不能被限制。
這是我嘗試過的:
class ArrayWrapper<T> {
constructor(private arr: T[]) {}
toMap<K, V>() {
return new Map(<T extends [K, V] ? [K, V][] : never>this.arr);
}
}
我也試過這個:
class ArrayWrapper<T> {
constructor(private arr: T[]) {}
toMap() {
return new Map(<T extends [infer K, infer V] ? [K, V][] : never>this.arr);
}
}
在上述兩種情況下,編譯器都給我一個“將型別 'T[]' 轉換為 ... 可能是一個錯誤,因為兩種型別都與另一個型別沒有充分重疊。如果這是故意的,請將運算式轉換為 'unknown'第一個”錯誤。
所以我嘗試了一些不同的東西,而不是從不,我將條件型別的 false 分支更改為never[]. 這擺脫了編譯錯誤,但是現在當我執行以下操作時:
class ArrayWrapper<T> {
constructor(private arr: T[]) {}
toMap() {
return new Map(<T extends [infer K, infer V] ? [K, V][] : never[]>this.arr);
}
}
const notConvertibleToMap = [1, 2, 3];
const convertibleToMap: [number, string][] = [[1, 'one'], [2, 'two'], [3, 'three']];
const arr1 = new ArrayWrapper(notConvertibleToMap);
const map1 = arr1.toMap();
const arr2 = new ArrayWrapper(convertibleToMap);
const map2 = arr2.toMap();
編譯器推斷地圖<未知,未知>兩個map1和map2。
我希望編譯器能夠:
- 在 的情況下
map1,當嘗試呼叫toMap()whenT既不會[K,V]給出錯誤,也不會至少推斷出回傳型別,never因為此函式呼叫將拋出錯誤,因為T它不是元組,而 Map 建構式將拋出. - 在
map2, whereTIS a的情況下[K, V],我希望編譯器正確推斷出Map<K, V>for的型別map2。
就像我一開始說的,T像這樣明顯限制了類中的型別
class ArrayWrapper<T extends [K, V], K, V> {
constructor(private arr: T[]) {}
toMap() {
return new Map(this.arr);
}
}
將允許對Kand進行正確推斷V,但我不想限制 T。我需要這個類來接受任何型別的包含值的陣列T。
對此進行了額外的嘗試:
class ArrayWrapper<T> {
constructor(private arr: T[]) {}
toMap() {
if (this.isArrayOfTuple(this.arr)) {
return new Map(this.arr);
}
throw new Error("called toMap() on ArrayWrapper that is not an array of tuples");
}
isArrayOfTuple<K, V>(arr: T[]): arr is [K, V][] {
return arr[0] instanceof Array && arr[0].length === 2;
}
}
but unfortunately the compiler is complaining over the return type of isArrayOfTuple, saying that
A type predicate's type must be assignable to its parameter's type.
Type '[K, V][]' is not assignable to type 'T[]'.
Type '[K, V]' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to '[K, V]'
uj5u.com熱心網友回復:
如果您希望編譯器在toMap()ifT不可分配給[K, V]some Kand 時呼叫錯誤V,那么從某種意義上說,在這種情況下輸出型別是什么并不重要。只要呼叫是編譯器錯誤,它就可以是Map<unknown, unknown>或Map<never, never>或任何東西toMap()。我認為您最終會遇到運行時錯誤(如果您真的關心,您可以仔細閱讀規范),因此該函式不會回傳......“實際”回傳型別是never可以安全地擴展為Map<unknown, unknown>或您想要的任何內容不會導致型別安全問題。
無論如何,為了使編譯器錯誤發生,您可以提供toMap()一個需要為 of或等效的this引數。您可以使用條件型別推斷來手動推斷和來自:thisArrayWrapper<[any, any]>KVT
toMap(this: ArrayWrapper<[any, any]>) {
type K = T extends [infer K, any] ? K : never;
type V = T extends [any, infer V] ? V : never;
return new Map<K, V>(this.arr);
}
但它使更簡單了toMap()一個通用的方法,并且具有K與V自動推斷:
toMap<K, V>(this: ArrayWrapper<[K, V]>) {
return new Map<K, V>(this.arr);
}
任何一種方法都會為您提供您正在尋找的行為:
const arr1 = new ArrayWrapper(notConvertibleToMap);
const map1 = arr1.toMap(); // <-- compiler error
// --------> ~~~~
// The 'this' context of type 'ArrayWrapper<number>' is not assignable to method's
// 'this' of type 'ArrayWrapper<[unknown, unknown]>'.
const arr2 = new ArrayWrapper(convertibleToMap);
const map2 = arr2.toMap(); // okay
// const map2: Map<number, string>
Playground 鏈接到代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/404574.html
標籤:
下一篇:如何在Julia中迭代Dict
