Let’s start with an example of TS

import { Button, ButtonProps } from './components/button'

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type BigButtonProps = Omit<ButtonProps, 'size'>

function BigButton(props: BigButtonProps) {
  returnButton({ ... props, size:'big'})}Copy the code

If this example is clear, please click on the upper right corner.

If not, we can go back and explore together.

partial, Readonly, Record, Pick

partial

Partial is used to make an attribute passed in optional.

keyof, in

First we need to understand the two keywords keyof and in. Keyof can be used to get all the keys of an object interface.

Such as

interface Foo {
  name: string;
  age: number
}

// T -> "name" | "age"
type T = keyof Foo 

type Keys = "a" | "b"
type Obj =  {
  [p in Keys]: any
} 
// Obj -> { a: any, b: any }
Copy the code

Keyof produces associative types, and in iterates through enumerated types, so they’re often used together. Look at the Partial source code

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

use

interface Foo {
  name: string;
  age: number;
}

typeB = Partial<Foo>; // Only attributes in name and age can be defined.let b: B = {
  name: '1',
  age: 3,
};
Copy the code

Required

Required makes the attribute passed in mandatory. The source code is shown below

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

We found an interesting use -? Well, it makes sense to represent the alternatives, right? Remove to make this type mandatory. And that corresponds to a plus, right? This meaning is naturally related to -? Instead, it was used to make properties optional.

Pick

Take a set of properties of K from T

type Pick<T, K extends keyof T> = { [P in K]: T[P] };
Copy the code

summary

Summarize Partial, Required, Pick.

type Partial<T> = {
  [P inkeyof T]? : T[P]; };type Required<T> = {
  [P inkeyof T]-? : T[P]; };type Pick<T, K extends keyof T> = {
  [P inK]: T[P]; }; interface User { age: number; name: string; }; // Equivalent to:typePartialUser = { age? : number; name? : string; }typePartialUser = Partial<User> // equivalent to:type PickUser = { age: number; name: string; }
type PickUser = Pick<User, "age" | "name">
Copy the code

Exclude

A condition type was introduced in TS 2.8, as shown below

T extends U ? X : Y
Copy the code

If T is a subtype of U, return X, otherwise return Y

type Exclude<T, U> = T extends U ? never : T;

const str: Exclude<'a' | '1' | '2'.'a' | 'y' | 'z'> = '1';
Copy the code

As you can see from the STR prompt, Exclude compares the previous type with the following type and filters out the attributes that are unique to the previous type

Combine a new type of Omit by using Pick and Exclude

Omit anything

// Pick
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
 
// Exclude
type Exclude<T, U> = T extends U ? never : T;

// Omit
type Omit = Pick<T, Exclude<keyof T, K>>
    
    
typeOmit<T, K> = Pick<T, Exclude<keyof T, K>>; interface User { id: number; age: number; name: string; } // equivalent to:type OmitUser = { age: number; name: string; }
type OmitUser = Omit<User, 'id'>;
Copy the code

Remove the ID attribute from the User interface.

conclusion

Let’s go back to the previous code

import { Button, ButtonProps } from './components/button'

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type BigButtonProps = Omit<ButtonProps, 'size'>

function BigButton(props: BigButtonProps) {
  returnButton({ ... props, size:'big'})}Copy the code

We first define a BigButtonProps type, which omits the size attribute. Solve!!!!!

The last

The whole article, if there are mistakes or not rigorous place, please be sure to give correction, thank you!

Reference: TS Advanced Techniques