React状态传入TableSortLabel三元运算符时TypeScript报错
解决TableSortLabel的TypeScript类型不匹配问题
错误信息
(property) direction?: "asc" | "desc" No overload matches this call. Overload 1 of 3, '(props: { href: string; } & { active?: boolean; direction?: "asc" | "desc"; hideSortIcon?: boolean; IconComponent?: ComponentType<{ className: string; }>; } & { action?: Ref<ButtonBaseActions>; ... 10 more ...; TouchRippleProps?: Partial<...>; } & CommonProps<...> & Pick<...>): Element', gave the following error. Type 'string' is not assignable to type '"asc" | "desc"'. Overload 2 of 3, '(props: { component: ElementType<any>; } & { active?: boolean; direction?: "asc" | "desc"; hideSortIcon?: boolean; IconComponent?: ComponentType<{ className: string; }>; } & { ...; } & CommonProps<...> & Pick<...>): Element', gave the following error. Type 'string' is not assignable to type '"asc" | "desc"'. Overload 3 of 3, '(props: DefaultComponentProps<ExtendButtonBaseTypeMap<TableSortLabelTypeMap<{}, "span">>>): Element', gave the following error. Type 'string' is not assignable to type '"asc" | "desc"'.ts(2769)
相关代码
import { Badge, Box, Drawer, IconButton, Table, TableBody, TableCell, TableContainer, TableSortLabel, TableHead, TableRow, Tooltip } from "@material-ui/core"; import { useEffect, useState } from "react"; function TeamsTableImpl({ a }: { a:number }) { const [orderDirection, setOrderDirection] = useState('asc') const [valueToOrderBy, setValueToOrderBy] = useState('team') const handleRequestSort = (event: any, property: any) => { const isAscending = (valueToOrderBy === property && orderDirection === 'asc') setValueToOrderBy(property) setOrderDirection(isAscending ? 'desc' : 'asc') } const createSortHandler = (property: any) => (event: any) => { handleRequestSort(event, property) } console.log(orderDirection); console.log(typeof(orderDirection)); const myorderDirection = "desc"; console.log(typeof(myorderDirection)) return ( <Box> <TableContainer style={{ marginTop: 32 }}> <Table> <TableHead> <TableRow> <TableCell> Team <TableSortLabel active={valueToOrderBy === "team"} direction = { valueToOrderBy === 'team' ? orderDirection : 'asc' } onClick={createSortHandler("team")}> Team </TableSortLabel> </TableCell> </TableRow> </TableHead> </Table> </TableContainer> </Box> ); }
依赖版本
"@material-ui/core": "^4.11.3", "react": "^17.0.1"
问题原因
TypeScript对useState('asc')的类型推断为普通string,但TableSortLabel的direction属性要求的是字面量联合类型"asc" | "desc"。普通string类型的范围远大于这个联合类型,因此无法通过类型检查。
而硬编码的"asc"/"desc"或直接定义的const myorderDirection = "desc"会被推断为字面量类型,符合属性的类型要求,所以不会报错。
解决方案
1. 显式指定useState的类型
直接为状态变量指定联合类型,约束其只能是"asc"或"desc":
const [orderDirection, setOrderDirection] = useState<"asc" | "desc">('asc')
2. 使用类型别名(可选,提升复用性)
如果该联合类型会在多处使用,可先定义类型别名:
type SortDirection = "asc" | "desc"; const [orderDirection, setOrderDirection] = useState<SortDirection>('asc')
3. 类型断言(不推荐,仅作备选)
在赋值给direction属性时,通过类型断言告诉TypeScript值符合要求:
<TableSortLabel active={valueToOrderBy === "team"} direction={valueToOrderBy === 'team' ? orderDirection as "asc" | "desc" : 'asc'} onClick={createSortHandler("team")}> Team </TableSortLabel>
效果验证
修改后,orderDirection的类型会被严格约束为"asc"|"desc",与TableSortLabel的direction属性类型完全匹配,编译错误即可消除。
内容的提问来源于stack exchange,提问作者user1601716
相关产品推荐
相关产品推荐

