JSON 值类型
定义完整且类型安全的 JSON 值类型。
JSON 值类型 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。
什么是 JSON 值
JSON 允许一组固定的值形状:字符串、数字、布尔值、空值、数组和对象。递归类型可以准确描述这组值。
type Json =
| string
| number
| boolean
| null
| Json[]
| { [k: string]: Json };
// arrays and objects nest Json again.递归 JSON 类型
关键在于:数组包含 Json,对象的值也是 Json,因此该类型会引用自身来表示嵌套数据。
type Json =
| string | number | boolean | null
| Json[]
| { [k: string]: Json };
const x: Json = { name: "Ada", tags: ["a", "b"], active: true };
console.log(x);JSON 原始值
最简单的 JSON 值是原始值。每种原始值都可以直接赋值给 Json。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const a: Json = "hello";
const b: Json = 42;
const c: Json = true;
const d: Json = null;
console.log(a, b, c, d);JSON 数组
JSON 数组是 Json[],因此可以容纳各种 JSON 值的混合,包括嵌套数组和对象。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const arr: Json = [1, "two", true, null, [3, 4]];
console.log(Array.isArray(arr));JSON 对象
JSON 对象通过索引签名将字符串键映射到 Json 值,从而支持任意嵌套。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const obj: Json = {
user: { name: "Ada", age: 36 },
scores: [10, 20, 30]
};
console.log(obj);深度嵌套的 JSON
由于该类型是递归的,因此无需任何额外声明,就能为深度嵌套的结构提供完整类型标注。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const deep: Json = {
a: { b: { c: [1, { d: true }] } }
};
console.log(deep);JSON 不包含的内容
Json 类型会正确拒绝 JSON 无法表示的值,例如 undefined、函数或 Date 对象。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
// const bad: Json = undefined; // Error
// const fn: Json = () => 1; // Error
const good: Json = { ok: true };
console.log(good);在运行时验证 JSON 形状
该类型描述了有效的 JSON,但您仍需在运行时验证不受信任的输入。递归类型守卫会检查每一层。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
function isJson(v: unknown): v is Json {
if (v === null) return true;
const t = typeof v;
if (t === "string" || t === "number" || t === "boolean") return true;
if (Array.isArray(v)) return v.every(isJson);
if (t === "object") return Object.values(v as object).every(isJson);
return false;
}
console.log(isJson({ a: [1, 2], b: "x" }));解析为 Json 类型
JSON.parse 返回 any,因此只有在验证之后才能将解析结果断言为 Json;或者先为变量标注类型,再进行验证。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const raw = "{ \"id\": 1, \"tags\": [\"a\"] }";
const parsed = JSON.parse(raw) as Json;
console.log(parsed);遍历 Json 值
递归遍历器可以遍历任意 JSON 值,只需检查运行时形状,即可分别处理原始值、数组和对象。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
function countLeaves(v: Json): number {
if (Array.isArray(v)) return v.reduce((a, x) => a + countLeaves(x), 0);
if (v !== null && typeof v === "object") return Object.values(v).reduce((a, x) => a + countLeaves(x), 0);
return 1;
}
console.log(countLeaves({ a: [1, 2], b: "x" }));Json 类型为何有用
精确的 Json 类型会明确记录哪些内容可以跨越 API 边界,并在编译时捕获序列化非 JSON 值的尝试。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
function send(payload: Json): string {
return JSON.stringify(payload);
}
console.log(send({ ok: true, items: [1, 2, 3] }));快速检查:JSON 值类型
请测试您对 JSON 值类型的理解。
回顾:JSON 值类型
您定义了一个涵盖原始值、数组和对象的递归 Json 类型,了解了它排除的内容,并使用递归类型守卫验证了不受信任的输入。
type Json = string | number | boolean | null | Json[] | { [k: string]: Json };
const data: Json = { id: 1, tags: ["a", "b"] };
console.log(JSON.stringify(data));常见问题解答
「JSON 值类型」课时是免费的吗?
是的 — 「JSON 值类型」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。
「JSON 值类型」这节课中我会学到什么?
定义完整且类型安全的 JSON 值类型。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 TypeScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「JSON 值类型」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 TypeScript Academy 课中编写并运行代码吗?
能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。