如何在TypeScript中访问AllChartOptions的series的data属性?
类型推断问题:无法访问ApexChart Series的data属性
问题背景
第三方库提供的类型定义如下:
export interface AllChartOptions { series: ApexAxisChartSeries | ApexNonAxisChartSeries; // ... 其他属性 }
series的具体类型实现:
export declare type ApexAxisChartSeries = { name?: string; type?: string; color?: string; group?: string; data: (number | null)[] | { x: any; y: any; // ... 其他属性 }[] | [number, number | null][] | [number, (number | null)[]][] | number[][]; }[]; export declare type ApexNonAxisChartSeries = number[];
尝试在series为ApexAxisChartSeries类型时,通过chart.series.map((singleSeries) => {...})遍历并访问singleSeries.data,但VSCode提示singleSeries的类型为:
singleSeries: number | { name?: string | undefined; type?: string | undefined; color?: string | undefined; group?: string | undefined; data: number[][] | (number | null)[] | { x: any; y: any; fill?: ApexFill | undefined; // ... 5 more 属性 columnWidthOffset?: number | undefined; }[] | [...][] | [...][]; }
且仅能调用toLocaleString、toString、valueOf方法,无法访问data属性。
原因分析
AllChartOptions.series是联合类型:ApexAxisChartSeries(对象数组)和ApexNonAxisChartSeries(数字数组)的组合。TypeScript在未做类型收窄的情况下,无法确定你遍历的是哪种数组:
- 如果是
ApexNonAxisChartSeries,遍历出的元素是number,不存在data属性 - 因此TypeScript会取两种类型的交集,只保留所有类型共有的方法,也就是
number和对象都具备的基础方法
解决方法
需要通过类型守卫收窄series的类型,确认其为ApexAxisChartSeries后再安全遍历:
方法1:自定义类型守卫函数(推荐)
function isApexAxisChartSeries(series: ApexAxisChartSeries | ApexNonAxisChartSeries): series is ApexAxisChartSeries { return Array.isArray(series) && series.every(item => typeof item === 'object' && item !== null && 'data' in item); } // 使用示例 if (isApexAxisChartSeries(chart.series)) { chart.series.map(singleSeries => { // 此处singleSeries类型已被正确推断,可直接访问data console.log(singleSeries.data); }); }
方法2:类型断言(仅确定场景使用)
如果能明确当前场景下series一定是轴图表类型,可直接用类型断言,但不推荐在不确定场景使用:
(chart.series as ApexAxisChartSeries).map(singleSeries => { console.log(singleSeries.data); });
方法3:遍历内部分支判断
也可以在map内部对每个元素做类型判断,分别处理两种情况:
chart.series.map(item => { if (typeof item === 'object' && item !== null && 'data' in item) { // 此处item类型被收窄为带data属性的对象 console.log(item.data); } else { // 处理非轴图表系列的数字元素 console.log('非轴图表系列元素:', item); } });
内容的提问来源于stack exchange,提问作者Tuma
相关产品推荐
相关产品推荐

