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

TypeScript中如何正确定义PHP传递的多维关联数组?

问题:TypeScript中如何正确描述PHP传递的多维关联数组?

我尝试在TypeScript中使用从PHP传递到前端的多维关联数组,为此定义了如下类型:

type AssociativeArray<T = unknown> = { [key: string]: AssociativeArray<T> | T | undefined | T[] };

但编译以下代码时:

type AssociativeArray<T = unknown> = { [key: string]: AssociativeArray<T> | T | undefined | T[] };

const exampleStatusJSON: AssociativeArray<string> = {
  available: "true",
  username: "Jean-loup",
  house: {
    room: {
      name: "Highcrest",
    },
  }
};

if ((typeof (exampleStatusJSON["house"]) !== "undefined") &&
            (typeof (exampleStatusJSON["house"]["room"]) !== "undefined") &&
            (typeof (exampleStatusJSON["house"]["room"]["name"]) !== "undefined")) {
    console.log("OK");
}

TypeScript在第二个和第三个条件处抛出错误:

Element implicitly has an 'any' type because expression of type "room" can't be used to index type 'string | AssociativeArray | string[]'.
Property 'room' does not exist on type 'string | AssociativeArray | string[]'.(7053)


解决方案

1. 用类型守卫明确嵌套对象类型

你的AssociativeArray类型允许值为字符串、数组或嵌套对象,TypeScript无法自动推断exampleStatusJSON["house"]一定是对象类型,需要通过类型守卫明确判断:

type AssociativeArray<T = unknown> = { [key: string]: AssociativeArray<T> | T | undefined | T[] };

const exampleStatusJSON: AssociativeArray<string> = {
  available: "true",
  username: "Jean-loup",
  house: {
    room: {
      name: "Highcrest",
    },
  }
};

// 定义类型守卫函数,判断值是否为嵌套的关联数组
function isAssociativeArray<T>(val: unknown): val is AssociativeArray<T> {
  return typeof val === 'object' && val !== null && !Array.isArray(val);
}

if (isAssociativeArray<string>(exampleStatusJSON["house"]) &&
    isAssociativeArray<string>(exampleStatusJSON["house"]["room"]) &&
    typeof exampleStatusJSON["house"]["room"]["name"] !== "undefined") {
    console.log("OK");
}

2. 针对固定结构定义精确类型

如果PHP返回的数据结构是固定的,直接定义精准类型比通用的AssociativeArray更实用,类型检查也更严格:

// 精确描述业务数据结构
type UserStatus = {
  available: string;
  username: string;
  house: {
    room: {
      name: string;
    };
  };
};

const exampleStatusJSON: UserStatus = {
  available: "true",
  username: "Jean-loup",
  house: {
    room: {
      name: "Highcrest",
    },
  }
};

// 此时无需额外判断,TypeScript可直接识别所有属性
if (exampleStatusJSON.house.room.name) {
  console.log("OK");
}

3. 用可选链+类型断言简化判断

如果不想编写类型守卫,也可以用**可选链操作符?.**结合类型断言快速处理,安全性稍弱但适合快速开发场景:

type AssociativeArray<T = unknown> = { [key: string]: AssociativeArray<T> | T | undefined | T[] };

const exampleStatusJSON: AssociativeArray<string> = {
  available: "true",
  username: "Jean-loup",
  house: {
    room: {
      name: "Highcrest",
    },
  }
};

if ((exampleStatusJSON["house"] as AssociativeArray<string>)?.["room"]?.["name"]) {
  console.log("OK");
}

内容的提问来源于stack exchange,提问作者parapente

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:06:24