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

如何从对象或数组的联合类型参数中简洁获取对象属性?

处理未导出类型的联合返回值

外部不可修改代码

// 外部代码,无法修改
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:09:22