Как использовать TypeScript «keyof» для создания интерфейса для универсального интерфейса API?

У меня возникли проблемы с использованием системы типов TypeScript для моделирования универсального интерфейса для вызова из Lua в TypeScript. Чтобы это работало, разработчик должен определить интерфейс TypeScript, определяющий методы TypeScript, к которым может обращаться Lua. Детали здесь не имеют большого значения, так как приведенный ниже простой пример иллюстрирует мое замешательство.

Как использовать TypeScript «keyof» для создания интерфейса для универсального интерфейса API?

Как видно из приведенного выше кода, у меня есть «ApiInterface», который определяет произвольные методы, которые разработчик может захотеть вызвать из Lua. Все такие методы принимают первый аргумент, который является объектом (похожим на «это»), а остальные аргументы могут быть любыми, которые разработчику нужно передать из Lua в метод TypeScript. На практике единственными типами, поддерживаемыми для этих оставшихся аргументов, являются примитивы, такие как число, строка, логическое значение, нуль. В приведенном выше примере кода я определил 3 таких метода API, но разработчик может определить любые методы по своему усмотрению. Весь смысл этого модуля Lua-to-TypeScript в том, чтобы быть универсальным и не привязанным к какому-либо конкретному определению «ApiInterface».

В конечном итоге среда выполнения упаковывает вызов метода Lua-to-TypeScript в объект типа ApiCall, который, как вы можете видеть, определен с полями для имени метода, объектом JavaScript, используемым для «этого», и оставшимися произвольными аргументами.

Чтобы проиллюстрировать мое замешательство, я показал KeyofDemo, чтобы проиллюстрировать ошибку TypeScript, которую я получаю. В классе KeyofDemo есть метод run, который хочет получить объект ApiCall и вызвать соответствующую функцию TypeScript/JavaScript.

Вы можете увидеть красную волнистую линию под фактическим вызовом метода в двух случаях. В одном случае нет дополнительных аргументов (помимо обязательного аргумента this), а в другом случае ApiCall.args фактически заполняется массивом аргументов для передачи из Lua в TypeScript.

Сообщение об ошибке из первого случая с красными волнистыми линиями: A spread argument must either have a tuple type or be passed to a rest parameter.

Сообщение об ошибке из второго случая с красными волнистыми линиями: Expected 3 arguments but got 1.

Ни одно из этих сообщений об ошибках не имеет для меня никакого смысла. Если я попытаюсь скомпилировать приведенный выше код TypeScript, компилятор сообщит об аналогичных ошибках.

Как я могу заставить систему типов TypeScript наилучшим образом моделировать поведение, которое я описал? На данный момент я обошел эту проблему, изменив строки 23 и 25 для регистра «this.api» на «любой», и это закрывает компилятор TypeScript. Но я хотел бы знать, как правильно смоделировать эту проблему.

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

spender 20.03.2022 01:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
43
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Первая ошибка связана с тем, что Javascript/Typescript не поддерживает использование операторов расширения в параметрах, если ваша функция не настроена для этого.

Вы должны настроить функцию для приема переменных параметров.

interface ApiInterface {
    apiMethod0(thisObj: Object, ...args: any[]): void
    apiMethod1(thisObj: Object, ...args: [string]): void
    apiMethod2(thisObj: Object, ...args: [number, boolean]): void
}

Смотрите этот код на игровой площадке

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

Хорошо, спасибо за объяснение - имеет смысл. Я был сбит с толку, потому что Javascript разрешает оператор распространения в этой ситуации; это Typescript запрещает это во имя безопасности типа параметра. Предложенные выше изменения в ApiInterface действительно удовлетворяют Typescript, но они представляют собой неудобный способ для будущих разработчиков определять свои функции Typescript. Это может быть менее запутанным для будущих разработчиков, которым придется определять для меня новые ApiInterfaces, чтобы реализация использовала приведение к «любому», что позволяет определять ApiInterface более интуитивно понятным способом.

deltamind106 21.03.2022 13:43

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