TypeScript adds a static typing system to JavaScript. Types that aggregate multiple elements in JavaScript, such as arrays and objects, correspond to index types in TypeScript.

For example, this is an index type:

type obj = {
  name: string;
  age: number;
  gender: boolean;
}
Copy the code

Index types can add modifiers readonly,? (Optional) :

type obj = {
  readonly name: string; age? :number;
  gender: boolean;
}
Copy the code

As we know, TypeScript supports type programming, where various operations are performed on type parameters (stereotypes) to produce new types:

type IsString<T> = T extends string ? true: false;
Copy the code

So with index types, how do you do an operation and generate a new type?

The answer is the mapping type.

Mapping type

Mapping types are used to construct new index types.

For example, this Record type:

type Record<K extends string | number | symbol, T> = { [P in K]: T; }
Copy the code

The Record type constructs an index type with key stirng or number or symbol and value of type T. It is an advanced type built into TS.

In the process of constructing a new index type, you can add some modifiers.

Such as ReadOnly:

type Readonly<T> =  {
  readonly [Key in keyof T]: T[Key];
}
Copy the code

It creates a new index type and adds the readonly modifier to each attribute of the original index type:

Such as Partial:

type Partial<T> = {
  [Key inkeyof T]? : T[Key] }Copy the code

It creates a new index type, superimposing? On each attribute of the original index type. Modification:

Can be added or removed:

Remove optional (?) :

type Required<T> = {
  [Key inkeyof T]-? : T[Key] }Copy the code

Remove the readonly:

type NotReadOnly<T> = {
  -readonly [Key in keyof T]: T[Key]
}
Copy the code

After these examples, it becomes clear what mapping types can do:

Mapping types can generate new index types by adding or removing readonly,? Modifier of the. The built-in types Record, ReadOnly, Required, Partial, and so on are mapping types.

However, the current mapping type still has limitations, cannot modify the index name, filtering and other operations, the function is not strong enough.

If you want to implement filtering and conversion, you need to remap the mapping type.

Heavy mapping

Remapping refers to adding an AS statement after an index to indicate what the index is converted to. It can be used to filter and convert index types.

For example, filter out indexes of type string:

type FilterString<T> = {
  [Key in keyof T as T[Key] extends string ? Key: never]: T[Key];
}
Copy the code

Return never to filter out, otherwise keep.

You can also convert the index by changing the index name and adding get:

type Getters<T extends Record<any.any>> = {
  [Key in keyof T as `get${Capitalize<Key & string>}`]: T[Key];
}
Copy the code

T extends XXX is a constraint given to a type parameter, indicating that only that type can be passed. The Record type here generates the index type, as we explained above, so T extends Record<any, any> constrains that only the index type can be passed in.

As is what converts the index to, so we’ve modified it, we’ve added GET, and capitalized it, and this Capitalize is also built into TS.

The effect is as follows:

These two examples illustrate that remapping AS can be used to filter and transform index types, and can be used for more flexible programming of index types.

For example, implement key and value interchangeably:

type Flip<T extends Record<any.any>> = {
  [Key in keyof T as `${T[Key]}`]: Key
}
Copy the code

With support for remapping, the mapping type can make more changes to the index type.

conclusion

TypeScript uses index types to represent aggregate types with multiple elements, such as arrays, objects, and so on.

TS supports type programming, which does various operations on type parameters and returns new types. You can also perform operations on index types, which are map types.

Mapping types In the process of generating a new index type, you can also add or remove readonly,? Modifier of the. The built-in Record, Required, Partial, and ReadOnly are all mapping types.

If you want to further filter and convert the index type, you need to use the remapping of AS, which can modify the index (filtering the index if the index is never).

Can use index type is just the basis, can use map type and remap is advanced content, this part can write a lot of complex type logic, belongs to the category of type gymnastics.