Error: T doesn‘t have .length
在 TypeScript 中,當我們使用泛型 <T>
時,有時會遇到一個常見問題:編譯器提示錯誤,指出泛型類型 T
不具備 .length
屬性。在本文中,我們將探討這個問題的解決方案,并介紹如何通過泛型約束或使用交叉類型和接口來確保我們可以安全地使用 .length
屬性。
問題背景
// error
function collectionProps<T>(arg: T): T {console.log(arg.length); // Error: T doesn't have .length return arg;
}
在上面的代碼中,我們嘗試訪問泛型類型 T
的 .length
屬性,但 TypeScript 編譯器提示錯誤,因為并不是所有類型都具備 .length
屬性。
解決方案
1: 使用數組類型
// success 1
function collectionProps<T>(arg: T[]): T[] { console.log(arg.length);return arg;
}
通過將參數類型限制為數組類型 T[]
,我們告訴編譯器我們期望傳入的參數具備數組的特性,包括 .length
屬性。這種方法是直觀且常用的解決方案。
2: 使用泛型約束
// 使用泛型約束
interface Lengthable {length: number;
}function collectionProps<T extends Lengthable>(arg: T): T {console.log(arg.length);return arg;
}
通過使用泛型約束,我們創建了一個接口 Lengthable
,表示具備 .length
屬性的類型。然后,在函數中,我們使用 extends
關鍵字將泛型 T
約束為 Lengthable
接口。這確保了我們可以安全地使用 .length
屬性。
3: 使用接口
// 使用接口
interface HasLength {length: number;
}function collectionProps<T extends HasLength>(arg: T): T {console.log(arg.length);return arg;
}
類似于第二種解決方案,我們也可以使用接口來定義具有 .length
屬性的類型。通過將泛型 T
約束為 HasLength
接口,我們達到了相同的效果。