This is the 15th day of my participation in wen Challenge

By mapping a type, you can generate a new type from an old type, for example

Make all attributes in a type/interface read-only

interface Obj {
  a: string;
  b: number;
  c: boolean;
}
/* ReadonlyObj = {readonly a: string; readonly b: number; readonly c: boolean; } * /
type ReadonlyObj = Readonly<Obj>;
Copy the code

Readonly source code implementation principle

/** * Make all properties in T readonly */
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};
Copy the code

Readonly is a generic interface of indexable type,

Index signature is P in keyof T,

T is the query operator for index type, representing the combined type of all attributes of type T,

P in is equivalent to performing a for in operation, which will bind variable P to the properties of T successively,

The return value of the index signature is an index access operator -t [P] that represents the type specified by the attribute P

Finally, adding readonly makes all properties read-only

Make all attributes in a type/interface optional

interface Obj {
  a: string;
  b: number;
  c: boolean;
}
/* Type inferred as type PartialObj = {a? : string | undefined; b? : number | undefined; c? : boolean | undefined; } * /
type PartialObj = Partial<Obj>;
Copy the code

Partial source code implementation principles

/** * Make all properties in T optional */
type Partial<T> = {
  [P inkeyof T]? : T[P]; };Copy the code

Extract some subset of a type/interface

interface Obj {
  a: string;
  b: number;
  c: boolean;
}
PickObj = {a: string; b: number; } * /
type PickObj = Pick<Obj, "a" | "b">;
Copy the code

Pick<T, K extends keyof T

/** * From T, pick a set of properties whose keys are in the union K */
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};
Copy the code

T is the object to be extracted

K has one constraint: it must be a union type from all property literals of T

The new type/attribute must be selected from K,

conclusion

These three types, officially called homomorphisms, only apply to specified attributes (Obj, above) and do not introduce new ones.

Create some new properties

interface Obj {
  a: string;
  b: number;
  c: boolean;
}

/* Type type RecordObj = {x: Obj; y: Obj; } * /
type RecordObj = Record<"x" | "y", Obj>;
Copy the code

RecordObj is a non-homomorphic type,

conclusion

A mapping type is essentially a predefined generic interface, often combined with an index type to get the attributes and attribute values of an object to map an object to the desired structure.