Skip to content

按键提取对象中的值

ts
const config = {
  host: "localhost",
  port: 8080,
  debug: true,
} as const;

// config.host = "127.0.0.1"; // Error: Cannot assign to 'host' because it is a read-only property.
// config.port = 9000;        // Error: Cannot assign to 'port' because it is a read-only property.
// config.debug = false;      // Error: Cannot assign to 'debug' because it is a read-only property.

function getConfigValue<K extends keyof typeof config>(
  key: K
): (typeof config)[K] {
  return config[key];
}

const host = getConfigValue("host"); // type: "localhost"
const port = getConfigValue("port"); // type: 8080
const debug = getConfigValue("debug"); // type: true

理解 getConfigValue 函数

这段代码定义了一个名为 getConfigValue 的函数,它从一个名为 config 的对象中获取指定键的值,并返回该值。为了更好地理解这个函数,我们需要逐步拆解其各个部分,包括类型参数、泛型约束、索引访问类型等。

代码解析

typescript
function getConfigValue<K extends keyof typeof config>(
  key: K
): (typeof config)[K] {
  return config[key];
}

1. typeof config

  • typeof 操作符在这里用于获取 config 对象的类型。

  • 假设 config 是如下定义的:

    typescript
    const config = {
      host: "localhost",
      port: 8080,
      debug: true,
    };

    那么 typeof config 就是:

    typescript
    {
      host: string;
      port: number;
      debug: boolean;
    }

2. keyof typeof config

  • keyof 操作符用于提取一个类型的键(属性名),并返回这些键的联合类型。
  • 在这个例子中,keyof typeof config 就是 "host" | "port" | "debug"

3. 泛型参数 K extends keyof typeof config

  • 这里的 K 是一个泛型参数,表示函数接受的键类型。
  • K extends keyof typeof config 约束了 K 必须是 config 对象的有效键之一,即 "host" | "port" | "debug" 中的一个。
  • 这确保了传递给 getConfigValue 函数的键确实是 config 对象中存在的键,从而提高了类型安全性。

4. 返回类型 (typeof config)[K]

  • 返回类型使用了索引访问类型 (typeof config)[K],这意味着返回的类型是 config 对象中与键 K 对应的属性类型。
  • 例如,如果 K"host",那么返回类型就是 string;如果 K"port",那么返回类型就是 number;如果 K"debug",那么返回类型就是 boolean

5. 函数体 return config[key];

  • 函数体直接返回 config 对象中与传入键 key 对应的值。
  • 因为 key 已经被约束为 config 对象的有效键,所以这里不会出现键不存在的情况,编译器可以安全地推断出返回值的类型。

示例解释

假设我们有以下 config 对象:

typescript
const config = {
  host: "localhost",
  port: 8080,
  debug: true,
};

我们可以这样使用 getConfigValue 函数:

typescript
const host = getConfigValue("host"); // 类型:string
console.log(host); // "localhost"

const port = getConfigValue("port"); // 类型:number
console.log(port); // 8080

const debug = getConfigValue("debug"); // 类型:boolean
console.log(debug); // true

// getConfigValue("unknown"); // Error: Argument of type '"unknown"' is not assignable to parameter of type '"host" | "port" | "debug"'

在这个例子中:

  • 调用 getConfigValue("host") 返回的是字符串 "localhost",并且 TypeScript 知道返回值的类型是 string
  • 调用 getConfigValue("port") 返回的是数字 8080,并且 TypeScript 知道返回值的类型是 number
  • 调用 getConfigValue("debug") 返回的是布尔值 true,并且 TypeScript 知道返回值的类型是 boolean
  • 如果尝试传递一个不在 config 对象中的键(如 "unknown"),TypeScript 编译器会抛出错误,确保类型安全。

总结

getConfigValue 函数通过泛型和索引访问类型实现了对 config 对象的安全访问。它不仅确保了传入的键是有效的,还能够精确地推断出返回值的类型,从而提高了代码的安全性和可维护性。

Released under the MIT License.