I was making some Table components using Next.js, typescript, and type-graphql.
There are various custom object types of data, but eventually, they should be rendered into table rows.
Even though the detailed shape of the row would be different because the shapes of each data are different,
They are the same in that they should be rendered into a list of rows.
所以我想根据列表数据的类型来制作泛型列表组件,以减少重复代码的编写.
I'll roughly explain the code with the types of data as animals.
Currently inside of CatList.tsx
:
const CatList = () => {
const { list, total } = useQuery(/* data fetching */)
// list is type of Cat[]
return (
<BaseTable>
{/* this block is what I wanted to make into generic components */}
{list.map((item: Cat) => (
<CatListRow data={item} /*...other props*/ />
)}
</BaseTable>
)
}
// same with dog in different file
const DogList = () => {
const { list, total } = useQuery(/* data fetching */)
// list is type of Dog[]
return (
<BaseTable>
{list.map((item: Dog) => (
<DogListRow data={item} /*...other props*/ />
)}
</BaseTable>
)
}
我想把每一张单子列成这样:
const CatList = () => {
const { list, total } = useQuery(/* data fetching */)
return (
<BaseTable>
<Rows list={list} /* ...other props */ />
</BaseTable>
)
}
我试着像这样赚Rows.tsx
美元:
type TableTarget = Cat | Dog | ... ;
/** each type has common fields
* __typename (string - ex: "Cat")
* id
* createdAt
* ...etc
*/
interface RowProps<T> {
data: T;
}
const CatRow = ({ data }: RowProps<Cat>) => {
/* Cat Row */
}
const DogRow = ({ data }: RowProps<Dog>) => {
/* Dog Row */
}
const getRowComponentByType = (target: TableTarget) => {
switch(target.__typename) {
case 'Cat':
return CatRow;
case 'Dog':
return DogRow;
...
}
}
interface RowsProps<T extends TableTarget> {
list: T[];
}
const Rows = <T>({ list }: RowsProps<T>) => {
if (list.length === 0) {
return (
<tr>list is empty.</tr>
)
}
const Row = getRowComponentByType(list[0])
return (
<>
{list.map((item: T) => {
<Row data={item} />
{/* red underline on 'data' prop */}
{/* error message: 'TableTarget' is not assignable to 'Cat & Dog' */}
})}
</>
)
}
export default Rows;
我想知道如何在正确使用打字脚本泛型的情况下完成Rows
组件.
提前谢谢您.