我有一個使用 next v10.1.2 和 Typescript v4.4.4 的 Nextjs 專案我想要一個SortableList封裝自定義型別串列的類。唯一的要求是該串列擴展了我的抽象類OrderedItem。
目前,當我嘗試訪問OrderedItem從新SortableList物件擴展的類上的屬性時遇到錯誤。
這在 Typescript 中是可能的,設定它的正確方法是什么?
代碼:
訂單項.ts
// The purpose of this class is to ensure that items in a list can be ordered.
abstract class OrderedItem {
order: number
constructor(order: number) {
this.order = order
}
}
export default OrderedItem
自定義串列項.ts
import OrderedItem from './OrderedItem'
// This is an example of a class that I would like to be orderable.
class CustomListItem extends OrderedItem {
name: string
jsx: JSX.Element
constructor(order: number, name: string, jsx: JSX.Element) {
super(order)
this.name = name
this.jsx = jsx
}
}
export default CustomListItem
SortableList.ts
import OrderedItem from './OrderedItem'
class SortableList {
// I want this array to be overridden by a custom class like CustomListItem
list: OrderedItem[]
constructor(list: OrderedItem[]) {
this.list = list
}
sortByOrder = (): void => {
this.list = this.list.sort((a, b) => a.order - b.order)
}
sortByReverseOrder = (): void => {
this.list = this.list.sort((a, b) => b.order - a.order)
}
}
export default SortableList
例子.tsx
import CustomListItem from './CustomListItem'
import SortableList from './SortableList'
export default function Example() {
const customList: CustomListItem[] = [
new CustomListItem(3, 'name3', <div></div>),
new CustomListItem(1, 'name1', <div></div>),
new CustomListItem(2, 'name2', <div></div>),
]
const sortableList: SortableList = new SortableList(customList)
sortableList.sortByOrder()
return sortableList.list.map(item => item.jsx)
}
我從這個例子中得到的錯誤是在example.tsx嘗試訪問jsx屬性時的 return 陳述句中,item因為 item 被鍵入為OrderedItem而不是CustomListItem。
錯誤:“OrderedItem”型別上不存在屬性“jsx”。
這樣做的正確方法是什么?我試著瞎搞與宣布SortableList與<T>和初始化它像
const sortableList = new SortableList<CustomListItem>(customList),但我不熟悉它應該如何作業。
uj5u.com熱心網友回復:
問題是當你訪問你SortableList的編譯器的一個元素時,它只知道它是一個OrderedItem沒有屬性的元素jsx。
對此有兩種主要解決方案:
- 您知道您的專案將始終屬于某種型別(如您的情況),并且您將其轉換為該型別。易于實作,但我真的警告你,這不是一個好主意,因為你會打破物件編程原則,而且這可能會導致很難除錯的運行時錯誤,例如你放置了一個不是的
CustomListItem串列中,也沒有財產jsx。這是如何完成的:
sortableList.list.map(item => (item as CustomListItem).jsx)
- 正式的方法是使用泛型。泛型只是代碼中型別的占位符,當您使用它時,它將被指定的型別替換。在您的情況下,您還需要對該泛型的約束,強制實作指定的型別擴展您的
OrderedItem類。這樣就不會出現意外錯誤的實際情況,因為 ts 編譯器通過檢查您的型別來阻止它們。在您的情況下,這是如何完成的:
SortableList.ts
import OrderedItem from './OrderedItem'
// T is the generic
// T extends OrderedItem is the constraint
class SortableList<T extends OrderedItem> {
// this array can contains only elements
// that are descendant of T
// T is always a descendant of OrderedItem
list: T[]
constructor(list: T[]) {
this.list = list
}
sortByOrder = (): void => {
this.list = this.list.sort((a, b) => a.order - b.order)
}
sortByReverseOrder = (): void => {
this.list = this.list.sort((a, b) => b.order - a.order)
}
}
export default SortableList
例子.tsx
import CustomListItem from './CustomListItem'
import SortableList from './SortableList'
export default function Example() {
const customList: CustomListItem[] = [
new CustomListItem(3, 'name3', <div></div>),
new CustomListItem(1, 'name1', <div></div>),
new CustomListItem(2, 'name2', <div></div>),
]
const sortableList: SortableList<CustomListItem> =
new SortableList<CustomListItem>(customList)
sortableList.sortByOrder()
return sortableList.list.map(item => item.jsx)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/346221.html
標籤:javascript 数组 打字稿 遗产 铸件
上一篇:具有嵌套類的類的Python行為
