You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:57:16