Indexed Access Types of TypeScript

preface

The official documents of TypeScript have already been updated, but the Chinese documents I can find are still in the older version. Therefore, some newly added and revised chapters are translated and sorted out.

This article is compiled from "TypeScript Handbook" Indexed Access Types "Chapter.

This article is not translated strictly according to the original text, and some contents are explained and supplemented.

text

We can use the indexed access type to find a specific attribute on another type:

type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];
// type Age = number

Because the index name itself is a type, we can also use union, keyof or other types:

type I1 = Person["age" | "name"];  
// type I1 = string | number
 
type I2 = Person[keyof Person];
// type I2 = string | number | boolean
 
type AliveOrName = "alive" | "name";
type I3 = Person[AliveOrName];  
// type I3 = string | boolean

If you try to find a property that does not exist, TypeScript will report an error:

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

Next is another example. We use number to get the type of array elements. Combined with typeof, you can easily capture the element types of array literals:

const MyArray = [
  { name: "Alice", age: 15 },
  { name: "Bob", age: 23 },
  { name: "Eve", age: 38 },
];
 
type Person = typeof MyArray[number];
       
// type Person = {
//    name: string;
//    age: number;
// }

type Age = typeof MyArray[number]["age"];  
// type Age = number

// Or
type Age2 = Person["age"];   
// type Age2 = number

Only types can be used as indexes, which means that you cannot create a variable reference using const:

const key = "age";
type Age = Person[key];

// Type 'key' cannot be used as an index type.
// 'key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?

However, you can implement similar refactoring using type aliases:

type key = "age";
type Age = Person[key];

Finally, let's talk about a practical case:

Suppose there is such a business scenario, a page should be used in different APP, such as Taobao, Tmall, Alipay. According to the different APP, the underlying API will be different.

const APP = ['TaoBao', 'Tmall', 'Alipay'];

function getPhoto(app: string) {
  // ...
}
  
getPhoto('TaoBao'); // ok
getPhoto('whatever'); // ok

If we only restrict the app to string type, even if other strings are passed in, there will be no error. We can use literal joint type constraints as follows:

const APP = ['TaoBao', 'Tmall', 'Alipay'];
type app = 'TaoBao' | 'Tmall' | 'Alipay';

function getPhoto(app: app) {
  // ...
}
  
getPhoto('TaoBao'); // ok
getPhoto('whatever'); // not ok

But writing twice is redundant. How can we get the string joint type of all its values according to an array? We can combine the typeof of the previous article with the content of this section to realize:

const APP = ['TaoBao', 'Tmall', 'Alipay'] as const;
type app = typeof APP[number];
// type app = "TaoBao" | "Tmall" | "Alipay"

function getPhoto(app: app) {
  // ...
}
  
getPhoto('TaoBao'); // ok
getPhoto('whatever'); // not ok

Let's analyze step by step:

First, use as const to change the array to the tuple type of readonly:

const APP = ['TaoBao', 'Tmall', 'Alipay'] as const;
// const APP: readonly ["TaoBao", "Tmall", "Alipay"]

However, at this time, app is still a value. We can obtain the type of APP through typeof:

type typeOfAPP = typeof APP;
// type typeOfAPP = readonly ["TaoBao", "Tmall", "Alipay"]

Finally, access the type through the index to obtain the string union type:

type app = typeof APP[number];
// type app = "TaoBao" | "Tmall" | "Alipay"

TypeScript series

  1. Narrowing of TypeScript
  2. More on Functions of TypeScript
  3. Object Type of TypeScript
  4. Generics of TypeScript
  5. Keyof Type Operator of TypeScript
  6. Typeof Type Operator of TypeScript

Wechat: "mqyqingfeng", add me to Yu Yu's only reader group.

If there is any mistake or lack of preciseness, please be sure to correct it. Thank you very much. If you like it or have some inspiration, welcome star, which is also an encouragement to the author.

Keywords: Javascript Front-end html5 TypeScript html

Added by garry_224 on Fri, 26 Nov 2021 01:04:58 +0200