Как называется событие, которое передает только аргументы типа в общую функцию в машинописном тексте?

Я изучаю дженерики машинописного текста. Я создал общую функцию, подобную следующей:


function getRandomElement<T>(items: T[]): T {
    let ranIndex = Math.floor(Math.random() * items.length);
    return items[ranIndex];
}

затем я намеренно вызвал эту функцию и передал только тип (не передавая аргумент в функцию).

let result = getRandomElement<number>;

Затем я ожидал, что компилятор Ts выдаст мне сообщение об ошибке создания оператора результирующей переменной, но ничего не произошло. результат после этого стал функцией ((items: number[]) => number). Я хочу больше узнать об этой особенности машинописного текста. Но после некоторого поиска я не нашел никакой важной информации.

Не могли бы вы помочь объяснить эту функцию или дать мне ключевое слово? Спасибо за внимание к моему глупому вопросу.

Это не совсем особенность TS. В JS функции являются первоклассными гражданами: их можно присваивать переменным, передавать в качестве аргументов, возвращать из функций. То же самое вы можете делать, скажем, со строками или числами. И вот что вы сделали — присвоили функцию getRandomElement переменной result. Это неотличимо (на уровне языка) от f = () => { console.info("this is a function") }, когда вы просто присваиваете функцию переменной. Это просто через другую переменную: g = f

VLAZ 27.08.2024 07:42

Машинописный текст @VLAZ добавляет отслеживание его типа. Он отличается от let result = getRandomElement; типом.

Caleth 27.08.2024 08:29

@Калет, но это почти не связано. fungtion fn<T>(x: T): T{} - это TS можно назвать fn<number>(42), который сначала будет удовлетворять общему параметру путем передачи <number>, а затем удовлетворять обычному параметру с помощью 42. Если вы опустите (42) в этом выражении, у вас останется универсальная функция, в которой удовлетворяется только общий параметр, но он не вызывается. На самом деле ничего особенного — у вас есть двухэтапный процесс, но вы делаете только первый шаг. Тогда, естественно, вам остается второй шаг. Хотя специального названия для него нет. Более того, ОП ожидал ошибку с fn<number>.

VLAZ 27.08.2024 08:51
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
3
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

let result = getRandomElement<number>;

Вы просто присвоили функцию переменной, и это полностью справедливо в JavaScript/Typescript. Вот почему TypeScript не будет жаловаться — вы не сделали ничего плохого — пока что ;-)

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

const dummyItems = ["one", "two", "three"];
const assignedFunction = getRandomElement<string>;
const resultOfRunningAssignedFunction = assignedFunction(dummyItems);

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

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

getRandomElement<number> — это выражение экземпляра , реализованное в microsoft/TypeScript#47607 и представленное в TypeScript 4.7.

Мы всегда могли вручную указать аргументы типа универсальной функции при ее вызове, например f<X, Y>(a, b, c):

declare const f: <T, U>(x: T, y: U, z: T[]) => [T, U]
// const f: <T, U>(x: T, y: U, z: T[]) => [T, U]    

declare const a: X;
declare const b: Y;
declare const c: X[];
f<X, Y>(a, b, c); // calling a generic function

но выражения создания экземпляров позволяют сделать это без его вызова, например f<X, Y>. То есть теперь можно написать (f<X, Y>)(a, b, c), где f<X, Y> — собственное выражение:

(f<X, Y>)(a, b, c); // calling an instantiation expression

Полученная функция (f<X, Y>) не является универсальной и может быть сохранена в отдельной переменной:

const g = (f<X, Y>);
// const g: (x: X, y: Y, z: X[]) => [X, Y]

Затем эту функцию можно вызвать повторно с аргументами того же типа:

g(a, b, c);
declare const d: X;
declare const e: Y;
g(d, e, [a, d]); 

Детская площадка, ссылка на код

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