Расширенные возможности TypeScript

TypeScript
Расширенные возможности TypeScript

Partial & Required

  • PartialПеревод как частичный / частичный / неполный, эта роль состоит в том, чтобы сделать все параметры интерфейса не требуемого
  • RequiredRequired<T>Функция состоит в том, чтобы сделать все атрибуты определенного типа обязательными.

декларация в тс

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

/**
 * Make all properties in T required
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};

Пример частичного использования

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

// 直接使用初始化所有参数都是必填
let tom:Person = {
    name: 'tom',
    age: 20
};


// 使用Partial将Person中所有的参数变为非必填
type PartialPerson = Partial<Person>;

let partialPerson: PartialPerson = {
  name: 'tom'
};

особые обстоятельства

type Person = {
  name: string;
  age: number;
  contact: {
    email: string;
    phone: number;
    wechat: string;
  }
}

type PartialPerson = Partial<Person>;

// 可以看出来 第一层属性都变成了非必填  第二层都没变
let partialPerson: PartialPerson = {
  name: 'tom',
  contact: { // error
    email: 'goodboyb@qq.com'
  }
};


// 再来看看ts内部类型的定义
/**
 * Make all properties in T optional
 */
type Partial<T> = {
    [P in keyof T]?: T[P];
};
// 可以看出来并没有考虑内层


// 稍微改造一下
/**
 * Make all properties in T optional
 */
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends Object ? DeepPartial<T[P]> : T[P];
}

// 现在针对那种特殊情况就能处理了

Требуемый пример использования

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;
// }

Record

RecordВ переводе запись/запись, роль заключается в сопоставлении всех значений атрибутов одного типа с другим типом и созданием нового типа

декларация в тс

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

Видно, что определение типа видно, и каждый атрибут ([PIN K]) превращен в тип T, а K может быть комбинацией, объектом, перечислением...

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

type numOrStr = number | string;

type IPets = Record<petsGroup, numOrStr>;

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

Pick

PickВ переводе как «выбор/выбор» функция состоит в том, чтобы взять комбинацию нескольких желаемых типов из составного типа для создания нового типа.

декларация в тс

/**
 * 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];
};

K extends keyof TФункция заключается в том, чтобы ключ K находился в ключе T и не мог превышать этот диапазон, иначе будет сообщено об ошибке.

keyof

  • keyof используется для получения всех ключей определенного типа, и его возвращаемый тип является типом объединения
// keyof 用于获取某种类型的所有键,其返回类型是联合类型
interface B {
  id: number;
  name: string;
  age: number;
}

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

extends

Расширения здесь используются не для наследования, а для ограничения типа

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

type K = {
  id: number;
}
type IType = K extends T ? K : T;
// type IType = {
//     id: number;
//     name: string;
// }
// 此处 K extends T 限制K中必须有T的所有属性, 通俗点说就是T必须是K的子集


// 联合类型extends
type T = "id" | "name";
type K = "id";
type IType = K extends T ? K : T;
// type IType = "id"
// 此处限制为K必须包含于T,通俗点说就是K是T的子集

использоватьPickВыбор нового типа атрибутов

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

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

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

Exclude

ExcludeПереводится как исключить/исключить,Exclude<T, U>Указывает, что те типы, которые могут быть присвоены U, исключаются из T. Проще говоря, некоторые типы, принадлежащие U в T, удаляются. Его также можно понимать как дополнительный набор

декларация в тс

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

пример

// 例子1
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"

Extract

Extractпереводится как экстракт,Extract<T, U>Извлечь те типы, которые можно присвоить U, из T. Проще говоря, это извлечение элементов в T, которые также есть в U, что также можно понимать как взятие пересечения.

Определение в тс

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

пример

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"

ConstructorParameters

ConstructorParametersПереведено как параметры конструктора, получите параметры типа конструктора в кортеже

декларация в тс

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

Тип кортежа, который можно использовать для получения типов параметров класса.

class People {
  name: string
  age: number

  constructor(name: string) {
    this.name = name;
  }
}


type IType = ConstructorParameters<typeof People>
// type IType = [name: string]
// 注意这里typeof操作是取类型的作用

infer

Представляет переменную типа, которая должна быть выведена в условном операторе extends.

// 例子1
// 若T是Array类型,则返回T的泛型,否则返回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
// 若T满足(param: infer P) => any,则返回函数入参的类型,否则直接返回T
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

пониматьinferмы оглядываемся назад на тсConstructorParametersзаявление

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

// T extends new (...args: any) => any 首先给T加了个约束 必须满足new (...args: any) => any 也就是说T必须是构造函数类型

// T extends new (...args: infer P) => any ? P : never
// T若满足new (...args: any) => any 则返回所有入参的类型, 否则返回never

InstanceType

InstanceTypeПреобразуется в тип экземпляра, используемый для получения возвращаемого типа конструктора.

Определение в тс

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

пример

class People {
  name: string
  age: number

  constructor(name: string) {
    this.name = name;
  }
}

type IType = InstanceType<typeof People>
// type IType = People
// 因为constructor默认返回this
// constructor People(name: string): People

NonNullable

NonNullableпереводится как не обнуляемый,NonNullable<T>Исключить null и undefined из T

Определение в тс

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

пример

type example = NonNullable<string | number | undefined>
// type example = string | number

Parameters & ReturnType

  • ParametersИспользуется для получения типа параметра функции
  • ReturnTypeИспользуется для получения типа возвращаемого значения функции

Определение в тс

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

Определение написано очень понятно, но подробнее

пример

type IFoo = (
  uname: string,
  uage: number
) => {
  name: string;
  age: number;
};
//参数类型
type Ibar = Parameters<IFoo>;
// type Ibar = [uname: string, uage: number]
type T0 = ReturnType<IFoo>;
// type T0 = {
//     name: string;
//     age: number;
// }

readonly & ReadonlyArray

  • readonlyтолько чтениеreadonlyОтмеченные свойства могут быть назначены только во время объявления или в конструкторе класса, и впоследствии они будут неизменяемыми (т. е. свойства только для чтения).
  • ReadonlyArrayТочно так же массив только для чтения
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>;
}

пример

interface Person {
  readonly id: number;
}
const data: Person = {
  id: 456,
};

data.id = 789;
// 无法分配到 "id" ,因为它是只读属性。ts(2540)

const arr: number[] = [1, 2, 3, 4];

let ro: ReadonlyArray<number> = arr;

ro.push(444);
// 类型“readonly number[]”上不存在属性“push”。ts(2339)

Суммировать

lib.es5.ts

Постоянный оригинальный адрес (ваша звезда - моя самая большая мотивация 🙂 )