Разница машинописного текста между размещением аргументов дженериков

В чем разница между общим синтаксисом функций:

type Identity<T> = (t: T) => T

и

type Identity = <T>(t: T) => T

?

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
3
0
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В TypeScript есть два различных варианта дженерики: универсальный функции и универсальный типы.


Универсальная функция объявляет свой параметр (или параметры) универсального типа в сигнатуре вызова функции:

type IdentityGenFunc = <T>(t: T) => T

Параметр типа в универсальной функции (T выше) не указывается до тех пор, пока функция не будет фактически вызвана, и в этот момент вызывающая сторона указывает ее (или компилятор выводит ее от имени вызывающей стороны). Это означает, что реализация универсальной функции должна иметь возможность обрабатывать любую возможную спецификацию T, которую хочет вызывающая функция:

const idGenFunc: IdentityGenFunc = x => x;

const resultABC = idGenFunc("ABC"); // T inferred here as ABC
// const resultABC: "ABC"
const result123 = idGenFunc(123); // T inferred here as 123
// const result123: 123

Универсальный тип объявляет свой параметр универсального типа (или параметры) в объявлении типа:

type IdentityGenType<T> = (t: T) => T

Параметр типа для универсального типа (T выше) должен быть указан, прежде чем вы сможете получить значение этого типа. Если у универсального типа есть сигнатура вызова или метод, который ссылается на параметр типа, этот параметр типа фиксируется, как только указан окружающий универсальный тип, до вызова этого метода. Если вы говорите, скажем, о IdentityGenType<string>, то его позывной должен уметь обрабатывать только string. И поэтому для реализации этой функции вам не нужно иметь дело с любым возможным значением T:

const idGenTypeString: IdentityGenType<string> = x => x + "!";

const resultABCagain = idGenTypeString("ABC"); // okay, "ABC" is assignable to string
// const resultABCagain: string
const result123Again = idGenTypeString(123); // error! 123 is not assignable to string

Эти две разновидности дженериков связаны друг с другом. Тип IdentityGenFunc по сути является «бесконечным пересечением» IdentityGenType<T> для всех возможных T. Система типов TypeScript недостаточно выразительна, чтобы сказать, что:

// the following is not valid TS, but this is what you want to say
type IdentityGenFunc = forall T, IdentityGenType<T>; // not valid TS, error

но вы можете засвидетельствовать это по заданиям:

// every IdGenFunc is also an IdGenType<number>
const idGenTypeNumber: IdentityGenType<number> = idGenFunc; // okay

С другой стороны, вы можете думать о IdentityGenType<T> как о IdentityGenFuncсозданный с некоторым типом T. Опять же, система типов не позволит вам выразить это:

// the following is not valid TS, but this is what you want to say
type GenType<T> = instantiate GenFunc with T; // not TS, error

Хотя TypeScript 4.7 представит выражения инстанцирования, который позволит вам создавать экземпляры параметров типа для ценность, тип которого является универсальной функцией:

// if you instantiate a value of type IdGenFunc with Date, then you get an IdGenType<Date> 
const idGenTypeDate: IdentityGenType<Date> = idGenFunc<Date>; // okay for TS4.7+

Ссылка на код для игровой площадки

Большое спасибо!

jkaczmarkiewicz 17.05.2022 22:38

Другие вопросы по теме