Partial & Required

  • PartialPartial/partial/incomplete, which makes all parameters of an interface non-mandatory
  • RequiredRequired to make all non-required parameters in an interface mandatory.Required<T>The attribute () function makes all attributes of a type mandatory.

Declaration in TS

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

Partial Usage Examples

type Person = {
  name: string;
  age: number;
}

All parameters are mandatory
let tom:Person = {
    name: 'tom'.age: 20
};


// Use Partial to make all parameters in Person non-mandatory
type PartialPerson = Partial<Person>;

let partialPerson: PartialPerson = {
  name: 'tom'
};
Copy the code

Special case

type Person = {
  name: string;
  age: number;
  contact: {
    email: string;
    phone: number;
    wechat: string; }}type PartialPerson = Partial<Person>;

// You can see that the first layer attributes are not required and the second layer remains unchanged
let partialPerson: PartialPerson = {
  name: 'tom'.contact: { // error
    email: '[email protected]'}};// Let's look at the internal type definition of ts
/** * Make all properties in T optional */
type Partial<T> = {
    [P inkeyof T]? : T[P]; };// The inner layer is not considered


// Modify it slightly
/** * Make all properties in T optional */
type DeepPartial<T> = {
  [P inkeyof T]? : T[P]extends Object ? DeepPartial<T[P]> : T[P];
}

// Now we can handle that special case
Copy the code

Required Usage examples

interface User {
  id: number;
  age: number;
}
type PartialUser = Partial<User>;
// type PartialUser = {
// id? : number;
// age? : number;
// }
type PickUser = Required<PartialUser>;
// type PickUser = {
// id: number;
// age: number;
// }
Copy the code

Record

Record, translated as Record, maps all attribute values of one type to another type and creates a new type

Declaration in TS

/** * Construct a type with a set of properties K of type T */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};
Copy the code

K can be a union type, an object, an enumeration…

type petsGroup = 'dog' | 'cat' | 'fish';

type numOrStr = number | string;

type IPets = Record<petsGroup, numOrStr>;

// type IPets = {
// dog: numOrStr;
// cat: numOrStr;
// fish: numOrStr;
// }
Copy the code

Pick

A new type is a combination of several desired types from a composite type

Declaration in TS

/** * 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

K extends Keyof T extends keyof T extends keyof T extends keyof T extends keyof T extends keyof T extends keyof T

keyof

  • Keyof is used to get all keys of a type whose return type is the union type
// keyof is used to get all keys of a type whose return type is the union type
interface B {
  id: number;
  name: string;
  age: number;
}

type B1 = keyof B;
// type B1 = "id" | "name" | "age"
Copy the code

extends

The extends here is not for inheritance, but rather to restrict types

/ / object extends
type T = {
  id: number;
  name: string;
}

type K = {
  id: number;
}
type IType = K extends T ? K : T;
// type IType = {
// id: number;
// name: string;
// }
// The K extends T extends T limits that K must have all properties of T


// The union type extends
type T = "id" | "name";
type K = "id";
type IType = K extends T ? K : T;
// type IType = "id"
// K is a subset of T
Copy the code

Use Pick to Pick properties to form new types

interface B {
  id: number;
  name: string;
  age: number;
}

type PickB = Pick<B, "id" | "name">;

// type PickB = {
// id: number;
// name: string;
// }
Copy the code

Exclude

Exclude, Exclude

, Exclude from T the types that can be assigned to U. In short, Exclude from T the types that belong to U. It can also be understood as taking a complement
,>

Declaration in TS

/** * Exclude from T those types that are assignable to U */
type Exclude<T, U> = T extends U ? never : T;
Copy the code

case

1 / / examples
type T = {
  name: string
  age: number
}

type U = {
  name: string
}

type IType = Exclude<keyof T, keyof U>
// type IType = "age"

type T0 = Exclude<"a" | "b" | "c"."a" | "b">
// type T0 = "c"
type T1 = Exclude<"a" | "b" | "c"."a" | "b" | 's'>
// type T1 = "c"
Copy the code

Extract

Extract

Extract from T the types that can be assigned to U
,>

Definition in TS

/** * Extract from T those types that are assignable to U */
type Extract<T, U> = T extends U ? T : never;
Copy the code

case

type T0 = Extract<"a" | "b" | "c"."a" | "f">
// type T0 = "a"

type T = {
  name: string
  age: number
}

type U = {
  name: string
}

type IType = Extract<keyof T, keyof U>
// type IType = "name"
Copy the code

ConstructorParameters

ConstructorParameters, translated as ConstructorParameters, get the parameters of the constructor type in a tuple

Declaration in TS

/** * Obtain the parameters of a constructor function type in a tuple */
type ConstructorParameters<T extends new(... args:any) = >any> = T extends new(... args: infer P) =>any ? P : never;

Copy the code

Can be used to get the tuple type of a class’s parameter types

class People {
  name: string
  age: number

  constructor(name: string) {
    this.name = name; }}type IType = ConstructorParameters<typeof People>
// type IType = [name: string]
// Note that the typeof operation is used to fetch the type
Copy the code

infer

Represents the type variable to be inferred in the extends condition statement

1 / / examples
// If T is Array, return the generic type of T, otherwise return never
type Union<T> = T extends Array<infer U> ? U: never

type a = {
  name: string
}

type b = string[]


type c  = Union<b>
// type c = string
type d = Union<a>
// type d = never


2 / / examples
Infer P => any; infer P => any
type ParamType<T> = T extends (param: infer P) => any ? P: T;
 
interface IDog {
    name: string;
    age:number;
}
 
type Func = (dog:IDog) = > void;
 
type Param = ParamType<Func>; // IDog
type TypeString = ParamType<string> //string
Copy the code

Infer After understanding infer we’ll come back to the statements of ConstructorParameters in TS

type ConstructorParameters<T extends new(... args:any) = >any> = T extends new(... args: infer P) =>any ? P : never;

// T extends new (... Args: any) => any Args: any) => any that means T must be of the constructor type

// T extends new (... args: infer P) => any ? P : never
// new (... Args: any) => any returns the types of all input parameters; otherwise, never is returned
Copy the code

InstanceType

InstanceType translates to the InstanceType, which is used to get the return type of the constructor

Definition in TS

/** * Obtain the return type of a constructor function type */
type InstanceType<T extends new(... args:any) = >any> = T extends new(... args:any) => infer R ? R : any;
Copy the code

case

class People {
  name: string
  age: number

  constructor(name: string) {
    this.name = name; }}type IType = InstanceType<typeof People>
// type IType = People
// Because constructor returns this by default
// constructor People(name: string): People
Copy the code

NonNullable

NonNullable

exclude null and undefined from T

Definition in TS

/** * Exclude null and undefined from T */
type NonNullable<T> = T extends null | undefined ? never : T;

Copy the code

case

type example = NonNullable<string | number | undefined>
// type example = string | number
Copy the code

Parameters & ReturnType

  • ParametersThe type used to get function arguments
  • ReturnTypeUsed to get the return value type of a function

Definition in TS

/** * Obtain the parameters of a function type in a tuple */
type Parameters<T extends(... args:any) = >any> = T extends(... args: infer P) =>any ? P : never;

/** * Obtain the return type of a function type */
type ReturnType<T extends(... args:any) = >any> = T extends(... args:any) => infer R ? R : any;
Copy the code

The definition is very clear, but I don’t want to go over it

case

type IFoo = (
  uname: string,
  uage: number
) = > {
  name: string;
  age: number;
};
// Parameter type
type Ibar = Parameters<IFoo>;
// type Ibar = [uname: string, uage: number]
type T0 = ReturnType<IFoo>;
// type T0 = {
// name: string;
// age: number;
// }
Copy the code

readonly & ReadonlyArray

  • readonlyRead-only byreadonlyAttributes of the tag can only be assigned at declaration time or in the constructor of the class, after which they are unchangeable (that is, read-only attributes).
  • ReadonlyArraySimilarly, read-only arrays
interface ReadonlyArray<T> {
    /** Iterator of values in the array. */
    [Symbol.iterator](): IterableIterator<T>;

    /** * Returns an iterable of key, value pairs for every entry in the array */
    entries(): IterableIterator<[number, T]>;

    /** * Returns an iterable of keys in the array */
    keys(): IterableIterator<number>;

    /** * Returns an iterable of values in the array */
    values(): IterableIterator<T>;
}
Copy the code

case

interface Person {
  readonly id: number;
}
const data: Person = {
  id: 456}; data.id =789;
// "id" cannot be assigned because it is read-only. ts(2540)

const arr: number[] = [1.2.3.4];

let ro: ReadonlyArray<number> = arr;

ro.push(444);
// The attribute "push" does not exist on type "readonly number[]". ts(2339)
Copy the code

conclusion

Ts has many features that can be viewed in lib.es5.ts. There are a lot of interfaces and types defined in ts.

Your star is my biggest motivation 🙂