WebStorm中MatDatepicker不匹配MatDatepicker<Moment>类型报错
WebStorm使用MatDatepicker组件类型报错问题
问题现象
在WebStorm中开发Angular应用使用MatDatepicker组件时,IDE报出两个类型错误:
- 类型
MatDatepicker无法赋值给MatDatepickerPanel<MatDatepickerControl<moment.Moment>, moment.Moment | null, moment.Moment>类型 - 参数类型
MatDatepicker无法赋值给MatDatepicker<Moment>类型参数
上述报错仅存在于IDE提示层面,应用可正常编译运行。相同代码在VS Code中无同类错误提示,Stackblitz环境下也无法复现报错,复现地址:Angular MatDatepicker复现示例
相关代码
组件HTML模板
<mat-form-field data-automation-id="inputs-form-field-input-on-primary-bg" appearance="legacy"> <mat-label>{{'ununterbrochener Besitz seit'}}</mat-label> <input matInput [matDatepicker]="picker" [max]="maxYear" formControlName="validFrom"/> <mat-hint>MM.YYYY</mat-hint> <mat-datepicker-toggle matSuffix [for]="picker" id="validFromPicker"></mat-datepicker-toggle> <mat-datepicker #picker startView="multi-year" (monthSelected)="setMonthAndYear($event, picker)"> </mat-datepicker> <mat-error *ngIf="checkError('validFrom','required')"> {{'vkb.insurance.data.entry.error.required'}} </mat-error> <mat-error *ngIf="checkError('validFrom','matDatepickerParse')"> {{'vkb.insurance.data.entry.error.pattern'}} </mat-error> <mat-error *ngIf="checkError('validFrom','matDatepickerMax')"> {{'vkb.insurance.data.entry.error.maxperiod'}} </mat-error> </mat-form-field>
组件TS代码
import { Component, OnInit } from '@angular/core'; import {FormControl, FormGroup, Validators} from '@angular/forms'; import {Router} from '@angular/router'; import {Customer} from '../../core/models/customer.model'; import moment, { Moment } from 'moment'; import {SharingDataService} from '../../shared/services/sharing-data.service'; import {MatDatepicker} from '@angular/material/datepicker'; @Component({ selector: 'app-new-beneficiary', templateUrl: './new-beneficiary.component.html', styleUrls: ['./new-beneficiary.component.scss'] }) export class NewBeneficiaryComponent implements OnInit { customerData: Customer = {}; currentPolicyholderForm: FormGroup; submitted = false; maxYear = moment(); constructor(private readonly router: Router, private readonly sharingDataService: SharingDataService) { this.currentPolicyholderForm = new FormGroup({ validFrom: new FormControl('', Validators.required) }, {}); } ngOnInit(): void { this.setValuesOnFormControls(); } private setValuesOnFormControls(): void { this.customerData = this.sharingDataService.client; if (this.currentPolicyholderForm && this.customerData) { this.currentPolicyholderForm.controls['validFrom'] .setValue(moment(this.customerData.validFrom)); } } public checkError = (controlName: string, errorName: string) => { return this.currentPolicyholderForm.controls[controlName].hasError(errorName); }; setMonthAndYear(normalizedMonthAndYear: Moment, datepicker: MatDatepicker<Moment>) { const ctrlValue = this.currentPolicyholderForm.controls['validFrom'].value!; ctrlValue.month(normalizedMonthAndYear.month()); ctrlValue.year(normalizedMonthAndYear.year()); this.currentPolicyholderForm.controls['validFrom'].setValue(ctrlValue); datepicker.close(); } }
模块配置代码
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import {CommonModule} from '@angular/common'; import {NewBeneficiaryComponent} from './new-beneficiary.component'; import {RouterModule} from '@angular/router'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatInputModule} from '@angular/material/input'; import {MatButtonModule} from '@angular/material/button'; import {OldBeneficiaryModule} from '../old-beneficiary/old-beneficiary.module'; import {TranslateModule} from '@ngx-translate/core'; import {MatDatepickerModule} from '@angular/material/datepicker'; import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core'; import {MomentDateAdapter, MomentDateModule, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter'; import {MONTH_YEAR_FORMAT} from '../../shared/formats/month-date-format'; @NgModule({ declarations: [NewBeneficiaryComponent], imports: [ CommonModule, RouterModule.forChild([ {path: '', component: NewBeneficiaryComponent} ]), TranslateModule, FormsModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule, OldBeneficiaryModule, MatDatepickerModule, MomentDateModule ], providers: [ {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]}, {provide: MAT_DATE_FORMATS, useValue: MONTH_YEAR_FORMAT} ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class NewBeneficiaryModule {}
解决思路
这类仅在WebStorm出现、运行无异常、其他环境无报错的假类型提示,按以下优先级排查解决:
- 明确模板变量类型:WebStorm对Angular模板中隐式模板变量的泛型推导能力弱于VS Code,可直接在组件类中通过
@ViewChild声明picker的明确类型,避免参数传递时类型不匹配:// 新增到组件类中 @ViewChild('picker') picker: MatDatepicker<Moment>; - 清理WebStorm缓存:点击菜单栏
File > Invalidate Caches...,勾选清除文件系统缓存选项后重启IDE,等待项目重新索引完成,绝大多数IDE缓存导致的假类型报错都会消失。 - 对齐依赖版本:检查
@angular/material、@angular/material-moment-adapter、moment三个依赖的版本是否完全匹配,版本不一致时可能出现类型定义偏差,对齐版本后删除node_modules和锁文件重新安装依赖即可。 - 调整严格模板检查配置:如果上述方案都无效,可检查
tsconfig.json中Angular编译器的严格模板检查配置,暂时关闭strictTemplates配置项验证是否为检查等级过高导致的误报。
内容的提问来源于stack exchange,提问作者Perez Ch
相关产品推荐
相关产品推荐

