如何从对象或数组的联合类型参数中简洁获取对象属性?
处理未导出类型的联合返回值
外部不可修改代码
// 外部代码,无法修改 type Point = { x: number; y: number; }; export const getPointData: (id: number) => Point | Point[] = (id: number) => { return getPoints(id); }
(注:原外部代码的类型标注存在语法错误,已修正为正确的函数类型 (id: number) => Point | Point[])
我方业务代码
// 我方代码 import { getPointData } from "something"; const pointData = getPointData(0); // 返回类型为Point | Point[]
问题
目前可以通过判断数组来处理pointData,但Point类型并未从库中导出,这种写法不够规范。想知道有没有更简洁的实现方式,当前的解决方案是不是唯一方法?
当前解决方案
const points = Array.isArray(pointData) ? { x: pointData[0].x, y: pointData[0].y } : { x: pointData.x, y: pointData.y }
(注:原代码中重复写了pointData[0].x,已修正为x和y的正确取值)
优化实现方案
提取单个点的简洁写法
如果你的需求是提取第一个点的x和y,可以直接通过三元表达式合并逻辑,一行代码搞定:
const { x, y } = Array.isArray(pointData) ? pointData[0] : pointData;
批量处理所有点的写法
如果需要处理所有点(包括数组中的多个点),可以先统一将数据转为数组,再用数组方法批量处理:
// 统一转为数组,确保后续逻辑一致 const normalizedPoints = Array.isArray(pointData) ? pointData : [pointData]; // 按需处理每个点,比如提取x、y const processedPoints = normalizedPoints.map(point => ({ x: point.x, y: point.y }));
更严谨的类型守卫(可选)
如果需要更严谨的类型判断,避免因数据结构异常导致报错,可以自定义类型守卫函数,不需要依赖未导出的Point类型:
// 自定义类型守卫,判断是否符合Point结构 function isPoint(item: unknown): item is { x: number; y: number } { return ( typeof item === 'object' && item !== null && 'x' in item && 'y' in item && typeof (item as any).x === 'number' && typeof (item as any).y === 'number' ); } // 使用类型守卫处理 let x: number, y: number; if (Array.isArray(pointData)) { const firstValidPoint = pointData.find(isPoint); if (firstValidPoint) { ({ x, y } = firstValidPoint); } } else if (isPoint(pointData)) { ({ x, y } = pointData); }
内容的提问来源于stack exchange,提问作者William Fallon
相关产品推荐
相关产品推荐

