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

使用MomentAdapter时,MUI DatePicker的onChange事件类型签名是什么?

MUI DatePicker搭配MomentAdapter时onChange的正确类型签名问题

问题说明

使用MUI的DatePicker搭配MomentAdapter时,控制台打印显示date是Moment对象,但TypeScript报错提示期望Date类型;在StackBlitz复现该场景时,date又变成了Date类型。需要明确onChange事件的正确类型签名。

用户原代码:

import * as React, { useState } from 'react';
import TextField from '@mui/material/TextField';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';

import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { Moment } from 'moment';

function App() {

  const [value, setValue] = useState<Moment | null>();

  return (
    <LocalizationProvider dateAdapter={AdapterMoment}>
      <DatePicker
        value={value}
        onChange={(date: Moment | null) => {
          setValue(date);
          console.log(date);
        }}
        renderInput={(params) => <TextField {...params} />}
      />
    </LocalizationProvider>
  )
}

原因解析

这个问题的核心是MUI X DatePicker的类型会随使用的适配器自动推断,但以下情况会导致类型不匹配:

  • 本地项目中实际运行时用了MomentAdapter,所以回调参数是Moment对象,但TypeScript没正确识别适配器对应的类型,因此报错期望Date。
  • StackBlitz中可能依赖版本不同,或者默认使用了原生Date适配器,所以参数类型变成了Date。

正确的类型处理方式

方式1:让TypeScript自动推断类型

直接移除onChange参数的手动类型声明,TypeScript会根据LocalizationProvider传入的AdapterMoment自动推断出参数类型为Moment | null,既省心又不会出错:

import * as React, { useState } from 'react';
import TextField from '@mui/material/TextField';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { Moment } from 'moment';

function App() {
  const [value, setValue] = useState<Moment | null>();

  return (
    <LocalizationProvider dateAdapter={AdapterMoment}>
      <DatePicker
        value={value}
        onChange={(date) => {
          setValue(date);
          console.log(date);
        }}
        renderInput={(params) => <TextField {...params} />}
      />
    </LocalizationProvider>
  )
}

方式2:显式指定DatePicker的泛型类型

如果需要手动指定类型,可以给DatePicker添加泛型参数Moment,明确它处理的日期类型,这样TS就能正确识别onChange的参数类型:

import * as React, { useState } from 'react';
import TextField from '@mui/material/TextField';
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { Moment } from 'moment';

function App() {
  const [value, setValue] = useState<Moment | null>();

  return (
    <LocalizationProvider dateAdapter={AdapterMoment}>
      <DatePicker<Moment>
        value={value}
        onChange={(date: Moment | null) => {
          setValue(date);
          console.log(date);
        }}
        renderInput={(params) => <TextField {...params} />}
      />
    </LocalizationProvider>
  )
}

额外注意点

  • 确保项目中@mui/x-date-pickers、@mui/material和moment的版本兼容,版本不匹配很容易导致类型推断异常。
  • 不要同时安装多个日期适配器(比如AdapterDateFns和AdapterMoment),避免类型冲突。

内容的提问来源于stack exchange,提问作者Sasgorilla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:50:30