2
头图

Preface

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

This article is organized from the " Indexed Access Types " chapter in the TypeScript Handbook.

This article does not strictly follow the original translation, but also explains and supplements part of the content.

text

We can use indexed access type (indexed access type) 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 element. Combining typeof can easily capture the element type of the array literal:

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

As the index can only be type, which means that you can not use const create a variable reference:

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 use type aliases to achieve a similar refactoring:

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

Finally, I will talk about a practical case:​

Suppose there is such a business scenario, a page needs to be used in different apps, such as Taobao, Tmall, and Alipay. Depending on the app, the underlying API called will be different. We might write like this:

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

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

If we just restrict the app to string type, even if other strings are passed in, it will not cause an error. We can use the literal joint type constraint:

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 a bit redundant. How do we get the string union type of all its values ​​based on an array? We can combine the typeof previous article and the content of this section to achieve:

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:

The first is to use as const change the array to the tuple type of readonly

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

But at this time APP is still a value, we get the type of APP 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

The TypeScript series of articles consists of three parts: official document translation, important and difficult analysis, and practical skills. It covers entry, advanced, and actual combat. It aims to provide you with a systematic learning TS tutorial. The entire series is expected to be about 40 articles. Click here to browse the full series of articles, and suggest to bookmark the site by the way.

WeChat: "mqyqingfeng", add me to the only reader group in Kongyu.

If there are mistakes or not rigorous, please correct me, thank you very much. If you like or have some inspiration, star is welcome, which is also an encouragement to the author.


冴羽
9.3k 声望6.3k 粉丝

17 年开始写前端文章,至今 6 个系列,上百篇文章,全网千万阅读