如何为含internal属性的TZDate数组定义类型而非使用any[]?
解决date-fns结合@date-fns/tz时TZDate类型的internal属性访问问题
问题场景
使用date-fns的eachMonthOfInterval结合@date-fns/tz的tz指定时区获取月份数组时,返回的元素是带internal属性的TZDate实例,但用TZDate[]作为类型时,访问internal会提示属性不存在。代码示例:
const startingMonth = "2024-10-01 00:00:00"; const endingMonth = "2024-12-01 00:00:00"; const allMonths: any[] = eachMonthOfInterval( { start: startingMonth, end: endingMonth, }, { in: tz("Asia/Calcutta"), } ); console.log(allMonths); console.log(allMonths[0].internal);
原因
internal是TZDate类的私有属性,@date-fns/tz的官方类型定义中并没有暴露这个属性,因此TypeScript会阻止直接访问它。
解决方案
1. 扩展TZDate类型声明(全局生效)
在项目的类型声明文件(比如types/date-fns-tz.d.ts)或者当前文件顶部添加以下代码,扩展TZDate的接口:
import { TZDate } from '@date-fns/tz'; declare module '@date-fns/tz' { interface TZDate { internal: Date; } }
之后就可以直接用TZDate[]作为allMonths的类型:
const allMonths: TZDate[] = eachMonthOfInterval(/* ... */); console.log(allMonths[0].internal); // 不再报错
2. 使用类型断言(临时场景)
如果只是临时需要访问该属性,不想修改全局类型,可以用类型断言绕过检查:
const allMonths = eachMonthOfInterval( { start: startingMonth, end: endingMonth }, { in: tz("Asia/Calcutta") } ) as (TZDate & { internal: Date })[]; console.log(allMonths[0].internal); // 正常访问
3. 优先使用公开API(推荐)
官方将internal设为私有是为了封装内部实现,直接依赖它会让代码面临库更新后失效的风险。建议使用TZDate提供的公开方法处理日期,比如:
// 获取时间戳 allMonths[0].getTime(); // 转为ISO格式字符串 allMonths[0].toISOString(); // 用date-fns工具函数处理 import { format } from 'date-fns'; format(allMonths[0], 'yyyy-MM-dd');
内容的提问来源于stack exchange,提问作者Harish
相关产品推荐
相关产品推荐

