Logo
Section 1 / 6

对象形状的类型定义

锁定你的对象结构,从 JavaScript 的猜测式编程升级到 TypeScript 的精确开发。

导入

对象形状的类型定义

锁定你的对象结构,从 JavaScript 的猜测式编程升级到 TypeScript 的精确开发。

1const user: { name: string; age: number } = { 2 name: "Alice", 3 age: 30, 4}; 5 6console.log(user.name); 7console.log(user);
1const user: { name: string; age: number } = { 2 name: "Alice", 3 extra: true, 4 name: 123, 5}; 6 7console.log(user);

解决方案与解析

1const user: { name: string; age: number } = { 2 name: "Alice", 3 age: 30, 4};

解释:

  • 第1行: 我们为 user 显式声明了一个对象类型:该对象必须包含 name(字符串类型)和 age(数字类型),不多不少。

  • 第2行和第4行: 我们移除了原始对象中重复的 name 键,并修正了类型问题。之前,字符串 "Alice" 被数值 123 覆盖,这会导致类型错误,因为 number 类型不能赋值给 string 类型。现在我们保留一个类型正确的单一 name 字段。

  • 第3行: 添加了缺失的 age 字段。如果没有这个字段,TypeScript 会报错,提示缺少必需属性。同时删除了多余的 extra 字段,该属性未在类型定义中声明,因此 TypeScript 会将其标记为非法添加。

解决方案与解析

1const user: { name: string; age: number } = { 2 name: "Alice", 3 age: 30, 4};

解释:

  • 第1行: 我们为 user 显式声明了一个对象类型:它必须包含 name(字符串)和 age(数字)。不多也不少。

  • 第2行和第4行: 移除了原始对象中重复的 name 键并修复了类型问题。此前,"Alice" 被 123 覆盖,导致类型错误,因为 number 无法赋值给 string。现在我们保留一个类型正确的单一 name 字段。

  • 第3行: 补充了缺失的 age 字段。否则 TypeScript 会报错,提示缺少必填属性。同时移除了额外的 extra 字段,该属性未在类型中定义,因此被 TypeScript 视为无效添加。

1type Product = { 2 id: number; 3 name: string; 4 description?: string; 5}; 6 7const pen: Product = { 8 id: 1, 9 name: "Ballpoint Pen", 10}; 11 12console.log(pen);
1type User = { 2 readonly id: number; 3 name: string; 4}; 5 6let bob: User = { id: 42, name: "Bob" }; 7bob.id = 99; // ❌ 错误:无法对 'id' 赋值,因为它是只读属性。 8 9console.log(bob);
1type Settings = { 2 username: string; 3 notifications?: { 4 email: boolean; 5 sms: boolean; 6 }; 7}; 8 9const userSettings: Settings = { 10 username: "charlie_dev", 11 notifications: { 12 email: true, 13 sms: false, 14 }, 15}; 16 17console.log(userSettings);
1// 在此处编写代码

显示答案

创建一个包含必需、可选、只读及嵌套字段的 ProjectConfig 对象

1type ProjectConfig = { 2 readonly id: number; 3 name: string; 4 description?: string; 5 settings: { 6 language: string; 7 features?: { 8 ci: boolean; 9 linting: boolean; 10 }; 11 }; 12}; 13 14const config: ProjectConfig = { 15 id: 1, 16 name: "AwesomeApp", 17 settings: { 18 language: "TypeScript", 19 features: { 20 ci: true, 21 linting: true, 22 }, 23 }, 24}; 25 26console.log(config);

解释:

  • 第1–12行: 使用 type 定义 ProjectConfig 类型,包含以下内容:

    • 第2行: id 是 number 类型,并标记为 readonly,确保后续不可重新赋值。

    • 第3行: name 是必需的 string 类型字段,必须提供。

    • 第4行: description 是可选(?)的字符串字段,可根据需要选择是否包含。

    • 第5–10行: settings 是一个嵌套对象,按要求定义。其内部包括:

      • 第6行: language 是必需的 string 类型字段。

      • 第7–9行: features 是一个可选的嵌套对象,包含两个必需的布尔字段:ci 和 linting。

  • 第14–24行: 创建满足 ProjectConfig 类型的 config 对象:

    • 第15–16行: 正确赋值 id 和 name。

    • 第17行: 包含必需的 settings 字段。

    • 第18行: 将 language 设置为 "TypeScript"。

    • 第19–22行: 提供了可选的 features 对象,结构正确且字段完整。

  • 第26行: 最后将 config 对象输出到控制台。

显示提示

提示:

  • 使用 ? 标记如 description 和 features 这类可选字段。

  • readonly 可防止 id 被意外重新赋值。

  • 记得完整定义嵌套的 features 对象类型。

  • 确保嵌套对象内部也遵循相同的规则——必需和可选字段在内层依然有效。

总结与下一步

类型别名与索引签名