Инвентаризация встроенных типов TypeScript

Инвентаризация встроенных типов TypeScript

Знание и понимание встроенных типов — важный шаг, когда разработчики начинают изучать TypeScript. TypeScript предоставляет ряд встроенных типов, которые помогают нам лучше определять и использовать переменные, функции и объекты.

Во- первых , TypeScript предоставляет базовые примитивные типы, включая number, string, и . Эти типы можно использовать для объявления основных типов данных переменных.booleannullundefined

Кроме того, TypeScript также предоставляет некоторые более продвинутые встроенные типы, такие как Array, и . Типы используются для определения массивов, типы используются для определения массивов фиксированной длины и определенного типа. Типы используются для определения типов перечисления, что позволяет нам давать более понятное имя группе связанных констант. Типы — это типы верхнего уровня в TypeScript, которые позволяют нам компилировать без проверки типов.TupleEnumAnyArrayTupleEnumAny

TypeScript также вводит некоторые более сложные встроенные типы, такие как Object, Functionи Promise. ObjectТипы используются для описания переменных не примитивных типов, Functionтипы — для описания функций, а Promiseтипы — для обработки результатов асинхронных операций.

Кроме того, TypeScript предоставляет несколько полезных встроенных типов, таких как Date, RegExpи Error. DateТипы используются для обработки дат и времени, RegExpтипы используются для обработки регулярных выражений, а Errorтипы используются для обработки ошибок.

Наконец, TypeScript также поддерживает некоторые расширенные операторы типов и вывод типов, такие как union, и . Эти функции делают определение и использование сложных типов в TypeScript более гибким и мощным.intersectiontype assertiontype inference

Понимание и знакомство с этими встроенными типами имеет решающее значение для написания надежного, удобного в сопровождении и типобезопасного кода TypeScript. Разумно используя эти типы, мы можем лучше выявлять ошибки во время разработки, улучшать качество кода и сокращать время отладки.

В этой статье вы познакомитесь с использованием некоторых продвинутых типов TypeScript и их реализацией.

Частичный

PartialИспользуется, чтобы сделать все свойства данного типа необязательными. Другими словами, Partialвы можете создать новый тип, имеющий те же свойства, что и исходный тип, но эти свойства являются необязательными.

Используя Partialможно легко определить объект, свойствам которого могут быть дополнительно присвоены значения. Это полезно в ситуациях, когда вам необходимо динамически устанавливать свойства объекта на основе контекста или когда вы хотите обновить только часть свойств объекта.

Вот пример, демонстрирующий, как использовать Partialинструмент «Текст»:

interface User {
    
    
  name: string;
  age: number;
  email: string;
}

function updateUser(user: Partial<User>): void {
    
    
  // 更新用户信息
  // ...
}

const user: User = {
    
    
  name: "John",
  age: 30,
  email: "[email protected]"
};

updateUser({
    
     name: "John Doe" }); // 仅更新名称
updateUser({
    
     age: 31, email: "[email protected]" }); // 仅更新年龄和邮箱

В приведенном выше примере мы определили интерфейс , Userкоторый имеет свойства и . Затем мы определяем функцию, которая принимает параметр типа, который является частично завершенным объектом.nameageemailupdateUserPartial<User>User

Используя его Partial<User>, мы можем updateUserпередавать только те свойства, которые необходимо обновить при вызове функции, не предоставляя полный Userобъект. Это позволяет нам легко обновлять только определенные свойства пользователя без необходимости изменять другие свойства.

Короче говоря, Partialинструмент типа — это полезный инструмент в TypeScript, который может помочь нам определить типы объектов с дополнительными свойствами и легко обновить некоторые свойства объекта, когда это необходимо.

Давайте посмотрим на его реализацию:

/**
 * Make all properties in T optional
 */
type Partial<T> = {
    
    
    [P in keyof T]?: T[P];
};
  • type Partial<T>: typeуниверсальный тип определяется с помощью ключевого слова Partial<T>, где T— параметр типа, указывающий тип, подлежащий обработке.
  • [P in keyof T]?: используйте оператор запроса типа индекса keyof T, чтобы получить Tвсе свойства типа, и используйте inключевое слово для перебора этих свойств. PЭто имя атрибута в процессе обхода, [P in keyof T]что означает создание атрибута нового типа с именем атрибута P.
  • ?: T[P]: используйте оператор необязательного атрибута ?, чтобы сделать значение атрибута необязательным. T[P]Указывает, что тип атрибута, определенного в новом типе, Tтакой же, как тип соответствующего атрибута исходного типа.

В совокупности Partial<T>функция заключается в Tпреобразовании всех свойств типа в необязательные свойства, то есть каждое свойство может иметь значение или не иметь значения. Этот тип часто используется в реальной разработке для частичного обновления или расширения объектов, чтобы облегчить выборочное назначение атрибутов.

Необходимый

RequiredИспользуется для установки всех свойств данного типа как обязательные. Другими словами, Requiredвы можете создать новый тип, имеющий те же свойства, что и исходный тип, но эти свойства являются обязательными и не могут быть пропущены.

Используя , Requiredвы можете легко определить объект, свойствам которого необходимо присвоить значения. Это полезно для обеспечения целостности объекта и безопасности типов.

Вот пример, демонстрирующий, как использовать Requiredинструмент «Текст»:

interface User {
    
    
  name?: string;
  age?: number;
  email?: string;
}

function createUser(user: Required<User>): void {
    
    
  // 创建用户
  // ...
}

createUser({
    
     name: "John", age: 30, email: "[email protected]" }); // 完整的用户信息
createUser({
    
     name: "John" }); // 缺少必需的属性,会报错

В приведенном выше примере мы определили Userинтерфейс, который имеет атрибуты и , но эти атрибуты являются необязательными, то есть их можно опустить name. Затем мы определяем функцию, которая принимает параметр типа, который является обязательным объектом.ageemailcreateUserRequired<User>User

Используя Required<User>, мы гарантируем, что при вызове createUserфункции Userдолжен быть предоставлен полный объект без пропуска каких-либо обязательных свойств. Это помогает гарантировать, что пользовательские объекты создаются с необходимой целостностью и безопасностью типов.

Давайте посмотрим на его реализацию:

/**
 * Make all properties in T required
 */
type Required<T> = {
    
    
    [P in keyof T]-?: T[P];
};
  • type Required<T>: typeуниверсальный тип определяется с помощью ключевого слова Required<T>, где T— параметр типа, указывающий тип, подлежащий обработке.
  • [P in keyof T]-?: используйте оператор запроса типа индекса keyof T, чтобы получить Tвсе свойства типа, и используйте inключевое слово для перебора этих свойств. PЭто имя атрибута в процессе обхода, [P in keyof T]что означает создание атрибута нового типа с именем атрибута P.
  • -?: T[P]: используйте оператор обязательного атрибута -?, чтобы сделать значение атрибута обязательным. T[P]Указывает, что тип атрибута, определенного в новом типе, Tтакой же, как тип соответствующего атрибута исходного типа.

В совокупности Required<T>функция заключается в Tпреобразовании всех атрибутов типа в обязательные атрибуты, то есть каждый атрибут должен иметь значение. Этот тип часто используется в реальной разработке для ограничения необходимых атрибутов объектов и обеспечения целостности и правильности атрибутов.

Только чтение

ReadonlyИспользуется для установки всех свойств данного типа в режим «только для чтения». Другими словами, Readonlyвы можете создать новый тип, имеющий те же свойства, что и исходный тип, но эти свойства доступны только для чтения и не могут быть изменены.

Используя Readonlyможно легко определить объект, доступный только для чтения, свойства которого нельзя изменить. Это полезно для обеспечения неизменности объекта и безопасности типов.

Вот пример, демонстрирующий, как использовать Readonlyинструмент «Текст»:

interface User {
    
    
  readonly name: string;
  readonly age: number;
  readonly email: string;
}

function getUser(): Readonly<User> {
    
    
  return {
    
     name: "John", age: 30, email: "[email protected]" };
}

const user: Readonly<User> = getUser();

console.log(user.name); // John
user.name = "John Doe"; // 无法修改只读属性,会报错

В приведенном выше примере мы определили Userинтерфейс, который имеет свойства и name, но эти свойства доступны только для чтения, то есть их нельзя изменить. Затем мы определяем функцию, которая возвращает пользовательский объект типа, доступный только для чтения.ageemailgetUserReadonly<User>

Используя , мы можем гарантировать, что свойства объекта пользователя не могут быть изменены после того, как они Readonly<User>присвоены переменной . userЭто помогает обеспечить неизменность объекта и безопасность типов.

Давайте посмотрим на его реализацию:

/**
 * Make all properties in T readonly
 */
type Readonly<T> = {
    
    
    readonly [P in keyof T]: T[P];
};
  • type Readonly<T>: typeуниверсальный тип определяется с помощью ключевого слова Readonly<T>, где T— параметр типа, указывающий тип, подлежащий обработке.
  • readonly [P in keyof T]: T[P]: используйте оператор запроса типа индекса keyof T, чтобы получить Tвсе свойства типа, и используйте inключевое слово для перебора этих свойств. PЭто имя атрибута в процессе обхода, [P in keyof T]что означает создание атрибута нового типа с именем атрибута P.
  • readonly: добавьте ключевое слово перед именем атрибута readonly, чтобы установить значение атрибута только для чтения.

В совокупности Readonly<T>его функция заключается в Tпреобразовании всех свойств типа в свойства, доступные только для чтения, то есть значение свойства не может быть изменено после присвоения. Этот тип часто используется в реальной разработке для защиты объектов от случайной модификации или изменения значений атрибутов.

Выбирать

PickИспользуется для выбора указанных свойств заданного типа и создания нового типа. Другими словами, Pickвы можете выбрать указанные свойства из типа объекта и создать новый тип, содержащий только указанные свойства.

Использование Pickпозволяет легко выбирать нужные части из сложного типа, сокращая ненужную избыточную информацию и улучшая читабельность и гибкость кода.

Вот пример, демонстрирующий, как использовать Pickинструмент «Текст»:

interface User {
    
    
  name: string;
  age: number;
  email: string;
  address: string;
}

type UserBasicInfo = Pick<User, "name" | "age">;

const user: UserBasicInfo = {
    
    
  name: "John",
  age: 30,
};

В приведенном выше примере мы определили Userинтерфейс со свойствами name, ageи . Затем мы используем инструмент «Текст», чтобы создать новый тип , который содержит только свойства и .emailaddressPickUserBasicInfonameage

С помощью Pick<User, "name" | "age">мы Userвыбираем атрибуты nameи ageиз типа и создаем новый тип UserBasicInfo. Затем мы можем использовать UserBasicInfoэтот тип для определения userобъекта, который содержит только свойства nameи age.

Давайте посмотрим на его реализацию:

/**
 * 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];
};
  • type Pick<T, K extends keyof T>: typeуниверсальный тип определяется с помощью ключевого слова Pick<T, K>, где T— параметр типа, указывающий тип, подлежащий обработке, K— параметр типа, указывающий набор ключей для выбранных атрибутов, K extends keyof Tуказывающий K, что он должен быть Tчастью набора ключей типа. .
  • [P in K]: T[P]: Kпредставляет ключевой набор атрибутов, которые необходимо выбрать, и использует inключевое слово для обхода этих атрибутов. P— это имя атрибута во время процесса обхода, [P in K]что означает создание атрибута нового типа с именем атрибута Pи только Kатрибутами, содержащимися в .

В совокупности Pick<T, K>функция заключается Tв выборе указанных атрибутов из типа и генерации нового типа. Этот тип часто используется в реальной разработке, когда необходимо извлечь некоторые атрибуты из большого типа.Можно точно выбрать необходимые атрибуты и избежать введения ненужных атрибутов.

Записывать

RecordИспользуется для создания типа объекта с указанным типом свойства. RecordПринимает два параметра типа: первый параметр указывает имя атрибута, а второй параметр указывает тип атрибута.

RecordВы можете легко определить тип объекта с указанным типом атрибута, используя , что очень полезно для создания структур данных, таких как словари и сопоставления.

Вот пример, демонстрирующий, как использовать Recordинструмент «Текст»:

type Fruit = "apple" | "banana" | "orange";
type Price = number;

const fruitPrices: Record<Fruit, Price> = {
    
    
  apple: 1.5,
  banana: 0.5,
  orange: 0.8,
};

console.log(fruitPrices.apple); // 1.5
console.log(fruitPrices.banana); // 0.5
console.log(fruitPrices.orange); // 0.8

В приведенном выше примере мы определили два типа Fruitи Price, Fruitкоторый представляет собой тип объединения, представляющий название фрукта, и Priceчисловой тип, представляющий цену фрукта.

Затем мы используем для Record<Fruit, Price>создания типа объекта fruitPrices, который может содержать только Fruitсвойства типа, а значение свойства должно быть Priceтипа.

Используя Record<Fruit, Price>, мы создали fruitPricesобъект с именем, который содержит три атрибута: яблоко, банан и апельсин, и их значения соответствуют их ценам соответственно.

Давайте посмотрим на его реализацию:

/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    
    
    [P in K]: T;
};
  • type Record<K extends keyof any, T>type: универсальный тип определяется с помощью ключевого слова Record<K, T>, где K— параметр типа, указывающий тип, который будет использоваться в качестве ключа атрибута, и T— параметр типа, указывающий тип значения атрибута. K extends keyof anyПредставители Kдолжны быть частью коллекции ключей любого типа.
  • [P in K]: T: используйте оператор запроса типа индекса keyof any, чтобы получить все ключи любого типа и inперебрать их, используя ключевое слово. PЭто имя ключа во время процесса обхода, [P in K]что означает создание атрибута нового типа, где имя атрибута Pи значение атрибута являются типом T.

В совокупности Record<K, T>результатом является создание нового типа, в котором ключом каждого атрибута является Kэлемент типа, а значением каждого атрибута является тип T. Этот тип часто используется в реальной разработке, когда необходимо создать объекты с определенными типами ключей и значений, и эти объекты можно легко определять и манипулировать ими.

Исключать

ExcludeИспользуется для исключения указанных типов из типа объединения.

ExcludeПринимает два параметра типа: первый параметр — это тип, который необходимо исключить, а второй параметр — тип объединения, из которого следует исключить типы.

Вот пример, демонстрирующий, как использовать Excludeинструмент «Текст»:

type Animal = "dog" | "cat" | "bird";
type ExcludeBird = Exclude<Animal, "bird">;

const myPets: ExcludeBird[] = ["dog", "cat"];

В приведенном выше примере мы определили тип объединения Animal, который содержит три типа животных dog: catи bird.

Затем мы Exclude<Animal, "bird">создали новый тип , используя ExcludeBirdтип, который исключил тип Animalиз type bird.

Наконец, мы определяем массив myPets, тип элемента которого равен ExcludeBird, то есть исключая birdтип Animal. Следовательно, myPetsмассив может содержать только dogи cat.

Используя Excludeинструменты типов, мы можем легко исключить определенный тип из типа объединения, чтобы создать новый тип для удовлетворения конкретных потребностей.

Давайте посмотрим на его реализацию:

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;
  • type Exclude<T, U>type: универсальный тип определяется с помощью ключевого слова Exclude<T, U>, где T— параметр типа, указывающий тип, подлежащий обработке, и U— параметр типа, указывающий тип, который необходимо исключить.
  • T extends U ? never : T: Используйте условные типы, чтобы определить T, может ли тип быть присвоен типу U. Если присвоение возможно, то есть Tявляется Uподтипом , neverвозвращается тип, указывающий, что тип исключен. Если не назначаемый, то есть Tне является Uподтипом , то Tвозвращается сам тип.

В совокупности Exclude<T, U>его функция состоит в том T, чтобы исключить Uиз типа все типы, которые можно присвоить типу, и сгенерировать новый тип. Этот тип часто используется в реальной разработке, когда указанный тип необходимо исключить из типа.Он может отфильтровать ненужные типы и повысить типобезопасность и гибкость кода.

Извлекать

ExtractИспользуется для извлечения указанного типа из типа объединения.

ExtractПринимает два параметра типа: первый параметр — это тип, который нужно извлечь, а второй параметр — тип объединения, из которого нужно извлечь тип.

Вот пример, демонстрирующий, как использовать Extractинструмент «Текст»:

type Animal = "dog" | "cat" | "bird";
type ExtractBird = Extract<Animal, "bird">;

const myBird: ExtractBird = "bird";

В приведенном выше примере мы определили тип объединения Animal, который содержит три типа животных dog: catи bird.

Затем мы Extract<Animal, "bird">создали новый тип , используя ExtractBirdтип, который извлек этот тип Animalиз type bird.

Наконец, мы определяем переменную myBirdтипа ExtractBird, которая извлекает birdтип Animaltype . Значит, myBirdэто может быть только так bird.

Используя Extractинструменты типов, мы можем легко извлечь конкретный тип из типа объединения, чтобы создать новый тип для удовлетворения конкретных потребностей.

Давайте посмотрим на его реализацию:

/**
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;
  • type Extract<T, U>type: Псевдоним типа определяется с помощью ключевого слова Extract<T, U>, где Tи U— параметры типа, представляющие тип, который будет обработан, и тип, который будет извлечен соответственно.
  • T extends U ? T : never: это условный тип, который использует условное суждение типа. Если тип Tможно присвоить типу , Uвозвращается Tсам тип, указывающий, что тип необходимо извлечь. Если тип Tне может быть присвоен типу U, возвращается тип never, указывающий, что тип не извлечен.

Этот псевдоним типа часто используется в реальных сценариях разработки, где необходимо сохранить только определенные типы.Типы можно фильтровать и обрабатывать на основе отношений типов, что повышает гибкость кода и безопасность типов.

Пропускать

OmitИспользуется для исключения указанных свойств из типа объекта.

OmitПринимает два параметра типа: первый параметр — это тип объекта, из которого следует исключить атрибут, а второй параметр — имя исключаемого атрибута.

Вот пример, демонстрирующий, как использовать Omitинструмент «Текст»:

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

type OmitAge = Omit<Person, "age">;

const personWithoutAge: OmitAge = {
    
    
  name: "John",
  gender: "male"
};

В приведенном выше примере мы определили тип объекта Personс тремя свойствами name: ageи gender.

Затем мы Omit<Person, "age">создали новый тип с помощью OmitAge, который исключил свойство Personиз типа age.

Наконец, мы определяем переменную , personWithoutAgeтип которой OmitAgeисключает тип ageсвойства Person. Таким образом, включены personWithoutAgeтолько атрибуты nameи .gender

Используя Omitинструменты типов, мы можем легко исключить указанные свойства из типа объекта и создать новый тип для удовлетворения конкретных потребностей.

Давайте посмотрим на его реализацию:

/**
 * Construct a type with the properties of T except for those in type K.
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
  • type Omit<T, K extends keyof any>type: Псевдоним типа определяется с помощью ключевого слова Omit<T, K extends keyof any>, где Tи Kявляются параметрами типа, представляющими обрабатываемый тип и исключаемые атрибуты соответственно.
  • Pick<T, Exclude<keyof T, K>>: это выражение, использующее два оператора типа. Сначала keyof Tполучите Tтип объединения, состоящий из всех имен атрибутов типа. Затем свойства, указанные в Exclude<keyof T, K>type, исключаются из объединения имен свойств type . KНаконец, выберите атрибуты, исключающие указанные атрибуты Pick<T, Exclude<keyof T, K>>из типа , чтобы создать новый тип.T

Этот псевдоним типа часто используется в реальных сценариях разработки, когда из типа необходимо удалить определенные атрибуты.Он может гибко управлять структурой и комбинацией типов, а также улучшать возможность повторного использования и обслуживания кода.

NonNullable

NonNullablenullИспользуется для исключения и из типа undefined.

NonNullableПринимает параметр типа, представляющий исключаемый тип nullи undefined.

Вот пример, демонстрирующий, как использовать NonNullableинструмент «Текст»:

type NullableString = string | null | undefined;
type NonNullableString = NonNullable<NullableString>;

const str: NonNullableString = "Hello";

В приведенном выше примере мы определили тип NullableString, который является типом объединения string, содержащим nullи .undefined

Затем мы NonNullable<NullableString>создаем новый тип, используя NonNullableString, который исключает и NullableStringв .nullundefined

Наконец, мы определяем переменную strтипа , что NonNullableStringисключает nullи . Итак, это может быть только тип.undefinedNullableStringstrstring

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

Давайте посмотрим на его реализацию:

/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T & {
    
    };
  • type NonNullable<T>: typeПсевдоним типа определяется с помощью ключевого слова NonNullable<T>, где T— параметр типа, указывающий тип, который будет обработан.
  • T & {}: Это выражение перекрестного типа. Типы пересечений используются для объединения нескольких типов в один тип. Здесь операция пересечения Tс {}(литеральным типом нулевого объекта) означает объединение типа Tи типа нулевого объекта в новый тип.

Этот псевдоним типа часто используется в реальных сценариях разработки, где необходимо гарантировать, что переменные или свойства не содержат nullили , что может повысить надежность и типобезопасность кода.undefined

Параметры

Parameters<T>Это универсальный тип утилиты, который используется для получения Tтипа параметра типа функции. Он принимает тип функции в качестве параметра и возвращает тип кортежа, содержащий тип каждого параметра функции.

Например, предположим следующее определение функции:

function greet(name: string, age: number): void {
    
    
  console.log(`Hello, ${
      
      name}! You are ${
      
      age} years old.`);
}

Вы можете Parametersполучить типы параметров функции, используя greet:

type GreetParams = Parameters<typeof greet>;
// GreetParams 的类型为 [string, number]

В этом примере GreetParamsтип выводится как тип кортежа, который содержит greetтипы двух параметров функции.

Давайте посмотрим на его реализацию:

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

В TypeScript — inferэто ключевое слово, используемое для определения переменных типа в условных типах. Условный тип — это способ вынесения условных суждений в системе типов, которая позволяет выбирать разные типы в соответствии с разными условиями. inferКлючевые слова можно использовать в предложениях условных типов, extendsчтобы определить конкретный тип переменной типа.

В условных типах inferключевые слова часто используются для привязки переменных типа к выводимому типу. Таким образом, при использовании условных типов inferэтот тип можно извлекать и манипулировать им с помощью ключевых слов.

В этом примере мы определяем Parameters<T>условный тип, который принимает тип функции Tв качестве параметра. Через inferключевое слово мы Rпривязываем переменную типа к параметру типа функции. Если Tэто тип функции, то Parameters<T>будет возвращен он R, то есть тип параметра функции; в противном случае будет возвращен он never.

inferИспользование ключевых слов позволяет нам выполнять вывод типов в условных типах, что позволяет нам более гибко действовать и обрабатывать различные типы ситуаций.

Параметры конструктора

ConstructorParametersИспользуется для получения типов параметров конструктора.

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

Вот пример, демонстрирующий, как использовать ConstructorParametersинструмент «Текст»:

class Person {
    
    
  constructor(name: string, age: number) {
    
    
    // constructor implementation
  }
}

type PersonConstructorParams = ConstructorParameters<typeof Person>;

const params: PersonConstructorParams = ["John", 25];

В приведенном выше примере мы определили Personкласс, у которого есть конструктор, принимающий один nameпараметр и один ageпараметр.

Затем мы используем для ConstructorParameters<typeof Person>создания нового типа PersonConstructorParams, который представляет собой тип кортежа, содержащий Personтипы параметров конструктора.

Наконец, мы определяем переменную params, тип которой представляет собой PersonConstructorParamsкортеж Personтипов параметров конструктора. Итак, paramsэто кортеж , содержащий nameи .age

Используя ConstructorParametersинструменты типов, мы можем легко получить типы параметров конструктора и использовать их для объявления переменных, параметров функций и т. д.

Давайте посмотрим на его реализацию:

/**
 * Obtain the parameters of a constructor function type in a tuple
 */
type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
  • type ConstructorParameters<T extends abstract new (...args: any) => any>: typeПсевдоним типа определяется с помощью ключевого слова ConstructorParameters<T extends abstract new (...args: any) => any>, где T— параметр типа, указывающий тип абстрактного конструктора, который необходимо обработать.
  • T extends abstract new (...args: infer P) => any ? P : never: Это выражение условного типа. Условные типы используются для выбора различных типов на основе определенного условия. Здесь T extends abstract new (...args: infer P) => anyуказано условие: если Tэто абстрактный тип конструктора, то он Pбудет выведен как массив типов аргументов конструктора. И ? Pозначает, что, когда условие истинно, вернуть Pмассив типов параметров; и : neverозначает, что, когда условие неверно, вернуть neverтип.

Этот псевдоним типа часто используется в реальных сценариях разработки, где тип параметра конструктора необходимо получить из типа абстрактного конструктора, и его можно использовать для вывода и использования типа параметра конструктора.

Тип возврата

ReturnType<T>Это универсальный тип утилиты, который используется для получения Tтипа возвращаемого значения типа функции. Он принимает тип функции в качестве параметра и возвращает тип возвращаемого значения функции.

Например, предположим следующее определение функции:

function add(a: number, b: number): number {
    
    
  return a + b;
}

Вы можете получить тип возвращаемого значения функции, ReturnTypeиспользуя :add

type AddResult = ReturnType<typeof add>;
// AddResult 的类型为 number

В этом примере AddResultпредполагается, что тип addвозвращаемого значения функции является numberтипом .

Давайте посмотрим на его реализацию:

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

ReturnType<T>Условный тип, который принимает тип функции Tв качестве параметра. С помощью inferключевого слова мы Rпривязываем переменную типа к возвращаемому значению типа функции. Если T — тип функции, то ReturnType<T>будет возвращен он R, то есть тип возвращаемого значения функции; в противном случае будет возвращено оно never.

Тип экземпляра

InstanceTypeИспользуется для получения типа экземпляра конструктора.

InstanceTypeПринимает тип конструктора в качестве параметра и возвращает тип экземпляра этого типа конструктора.

Вот пример, демонстрирующий, как использовать InstanceTypeинструмент «Текст»:

class Person {
    
    
  name: string;
  age: number;

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

  sayHello() {
    
    
    console.log(`Hello, my name is ${
      
      this.name} and I'm ${
      
      this.age} years old.`);
  }
}

type PersonInstance = InstanceType<typeof Person>;

const person: PersonInstance = new Person("John", 25);
person.sayHello();

В приведенном выше примере мы определили Personкласс, у которого есть конструктор и несколько методов экземпляра.

Затем мы InstanceType<typeof Person>создаем новый тип, используя тип экземпляра PersonInstanceконструктора Person.

Наконец, мы определяем переменную person, тип которой является типом PersonInstanceэкземпляра Personконструктора. Мы new Person("John", 25)создаем Personэкземпляр и присваиваем его person.

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

Давайте посмотрим на его реализацию:

/**
 * Obtain the return type of a constructor function type
 */
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
  • type InstanceType<T extends abstract new (...args: any) => any>: typeПсевдоним типа определяется с помощью ключевого слова InstanceType<T extends abstract new (...args: any) => any>, где T— параметр типа, указывающий тип абстрактного конструктора, который необходимо обработать.
  • T extends abstract new (...args: any) => infer R ? R : any: Это выражение условного типа. Условные типы используются для выбора различных типов на основе определенного условия. Здесь T extends abstract new (...args: any) => infer Rуказано условие: если Tэто абстрактный тип конструктора, то он Rбудет интерпретироваться как тип экземпляра конструктора. И ? Rозначает, что, когда условие истинно, вернуть Rтип экземпляра конструктора; и : anyозначает, что, когда условие неверно, вернуть anyтип.

Этот псевдоним типа часто используется в реальных сценариях разработки, где необходимо получить тип экземпляра конструктора из типа абстрактного конструктора, и может использоваться для вывода и использования типа экземпляра конструктора.

Верхний регистр

UppercaseИспользуется для преобразования букв строкового типа в верхний регистр.

UppercaseПринимает строковый тип в качестве аргумента и возвращает версию этого строкового типа в верхнем регистре.

Вот пример, демонстрирующий, как использовать Uppercaseинструмент «Текст»:

type UppercaseString = Uppercase<"hello">;
// UppercaseString 的类型为 "HELLO"

const str: UppercaseString = "HELLO";

В приведенном выше примере мы Uppercase<"hello">создали новый тип, используя UppercaseString, который является "hello"версией строкового типа в верхнем регистре, "HELLO"т.е.

Затем мы определяем переменную , strтип которой — UppercaseStringверсия строкового типа в верхнем регистре. Мы "HELLO"присваиваем строку str.

Используя Uppercaseинструменты типов, мы можем удобно преобразовывать буквы строкового типа в верхний регистр и использовать их в объявлениях типов.

Давайте посмотрим на его реализацию:

/**
 * Convert string literal type to uppercase
 */
type Uppercase<S extends string> = intrinsic;
  • type Uppercase<S extends string>: typeПсевдоним типа определяется с помощью ключевого слова Uppercase<S extends string>, где S— параметр типа, указывающий тип строки, подлежащей обработке.
  • intrinsic: это заполнитель для фактического встроенного типа или функции. Здесь intrinsicпредставлена ​​внутренняя реализация преобразования символов строковых типов в верхний регистр.

В совокупности Uppercase<S>функция предназначена для Sпреобразования символов строкового типа в верхний регистр и возврата нового типа.

Следует отметить, что в этом коде intrinsicэто всего лишь заполнитель для представления внутренней реализации, а не самого кода. В реальной разработке мы можем использовать встроенный тип, предоставляемый TypeScript, Uppercase<S>для реализации функции преобразования символов строковых типов в верхний регистр.

строчные буквы

LowercaseИспользуется для преобразования букв строкового типа в нижний регистр.

LowercaseПринимает строковый тип в качестве аргумента и возвращает версию этого строкового типа в нижнем регистре.

Вот пример, демонстрирующий, как использовать Lowercaseинструмент «Текст»:

type LowercaseString = Lowercase<"HELLO">;
// LowercaseString 的类型为 "hello"

const str: LowercaseString = "hello";

В приведенном выше примере мы Lowercase<"HELLO">создали новый тип, используя LowercaseString, который является "HELLO"строчной версией строкового типа, "hello"т.е.

Затем мы определяем переменную , strтип которой LowercaseString— строчная версия строкового типа. Мы "hello"присваиваем строку str.

Используя Lowercaseинструменты типов, мы можем удобно преобразовывать буквы строкового типа в нижний регистр и использовать их в объявлениях типов.

Давайте посмотрим на его реализацию:

/**
 * Convert string literal type to lowercase
 */
type Lowercase<S extends string> = intrinsic;
  • type Lowercase<S extends string>: typeПсевдоним типа определяется с помощью ключевого слова Lowercase<S extends string>, где S— параметр типа, указывающий тип строки, подлежащей обработке.
  • intrinsic: это заполнитель для фактического встроенного типа или функции. Здесь intrinsicпредставлена ​​внутренняя реализация преобразования символов строковых типов в нижний регистр.

Следует отметить, что в этом коде intrinsicэто всего лишь заполнитель для представления внутренней реализации, а не самого кода. В реальной разработке мы можем использовать встроенный тип, предоставляемый TypeScript, Lowercase<S>для реализации функции преобразования символов строковых типов в нижний регистр.

капитализировать

CapitalizeИспользуется для преобразования первого символа строки в верхний регистр.

Например:

type MyString = 'hello';
type CapitalizedString = Capitalize<MyString>;
// CapitalizedString 的类型为 'Hello'

В приведенном выше примере мы используем Capitalizeинструмент типа для MyStringпреобразования первого символа строкового типа в верхний регистр и присваиваем результат псевдониму типа CapitalizedString. Поскольку MyStringзначение is 'hello', CapitalizedStringтип is 'Hello'.

Обратите внимание, что это Capitalizeможно применить только к строковым типам. Если вы попытаетесь применить его к другим типам (например, числам, логическим значениям) Capitalize, вы получите ошибку времени компиляции.

Давайте посмотрим на его реализацию:

/**
 * Convert first character of string literal type to uppercase
 */
type Capitalize<S extends string> = intrinsic;

Декапитализировать

UncapitalizeИспользуется для преобразования первого символа строки в нижний регистр.

Например:

type MyString = 'Hello';
type UncapitalizedString = Uncapitalize<MyString>;
// UncapitalizedString 的类型为 'hello'

В приведенном выше примере мы используем Uncapitalizeинструмент типа для MyStringпреобразования первого символа строкового типа в нижний регистр и присваиваем результат псевдониму типа UncapitalizedString. Поскольку MyStringзначение is 'Hello', UncapitalizedStringтип is 'hello'.

Обратите внимание, что это Uncapitalizeможно применить только к строковым типам. Если вы попытаетесь применить его к другим типам (например, числам, логическим значениям) Uncapitalize, вы получите ошибку времени компиляции.

Давайте посмотрим на его реализацию:

/**
 * Convert first character of string literal type to lowercase
 */
type Uncapitalize<S extends string> = intrinsic;

Guess you like

Origin blog.csdn.net/p1967914901/article/details/132024098