按索引访问的类型

我们可以访问某个类型上的特定属性,从而获取该属性的类型。这种类型称为按索引访问的类型。

  1. type Person = { age: number; name: string; alive: boolean };
  2. type Age = Person["age"];
  3. ^^^
  4. // type Age = number

索引类型本身也是一个类型,所以它完全可以和联合类型、keyof 或者其它类型搭配使用:

  1. type I1 = Person["age" | "name"];
  2. ^
  3. // type I1 = string | number
  4. type I2 = Person[keyof Person];
  5. ^
  6. // type I2 = string | number | boolean
  7. type AliveOrName = "alive" | "name";
  8. type I3 = Person[AliveOrName];
  9. ^
  10. // type I3 = string | boolean

如果尝试索引一个不存在的属性,则会抛出错误:

  1. type I1 = Person["alve"];
  2. ^^^^^^
  3. // Property 'alve' does not exist on type 'Person'.

此外,我们还可以使用 number 获取数组元素的类型。我们可以将其与 typeof 相结合,方便地捕获数组字面量的元素类型:

  1. const MyArray = [
  2. { name: "Alice", age: 15 },
  3. { name: "Bob", age: 23 },
  4. { name: "Eve", age: 38 },
  5. ];
  6. type Person = typeof MyArray[number];
  7. ^^^^^^
  8. /* type Person = {
  9. name: string;
  10. age: number;
  11. } */
  12. type Age = typeof MyArray[number]["age"];
  13. ^^^
  14. // type Age = number
  15. // 或者
  16. type Age2 = Person["age"];
  17. ^^^
  18. // type Age2 = number

你只能使用类型作为索引,也就是说,使用 const 创建的变量引用是不能作为索引的:

  1. const key = "age";
  2. type Age = Person[key];
  3. ^^^^
  4. /*
  5. Type 'key' cannot be used as an index type.
  6. 'key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?
  7. */

不过,你可以改用类型别名重写这段代码:

  1. type key = "agr";
  2. type Age = Person[key];