Создание случайного миксина в TypeScript

Я работаю над ChanceJS миксин, который планирую распространять через npm.

У меня возникают проблемы с определением правильного интерфейса и типизации.

Пример пакета: // index.ts

import * as Chance from 'chance';

export interface ITime {
  time(): string;
}

function time() {
  const h = chance.hour({ twentyfour: true });
  const m = chance.minute();
  return `${h}:${m}`;
};

export const time: ITime = {
  time,
};

Пример того, как кто-то будет его употреблять:

import * as Chance from 'chance';
import { time } from 'chance-time';

const chance = new Chance();
chance.mixin(time);

chance.time()

Я получаю следующую ошибку:

Error:(12, 14) TS2345: Argument of type 'ITime' is not assignable to parameter of type 'MixinDescriptor'.
Index signature is missing in type 'ITime'.
Error:(25, 26) TS2339: Property 'time' does not exist on type 'Chance'.
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой 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 для повышения производительности приложения путем загрузки модулей только тогда, когда они...
2
0
882
3

Ответы 3

Похоже, что Определения определенного типа для ChanceJS на самом деле не поддерживает то, что вы пытаетесь сделать. Идеальным решением для этого было бы изменение этих типов ввода, но если вы не хотите этого делать, утверждения типа будут вашим другом.

У меня не установлен ChanceJS, поэтому вам может потребоваться изменить следующий код (пространства имен и т. д.), Чтобы он заработал:

const chance = new Chance() as Chance.Chance & ITime;
chance.mixin(time as any); // no error
chance.time(); // no error now I hope

В первой строке идея состоит в том, что chance в конечном итоге станет одновременно и Chance, и ITime, поскольку это то, что делает функция микширования. Это позволит линии chance.time() компилироваться без ошибок.

Во второй строке вы просто подавляете ошибку «отсутствует подпись индекса». Есть и другие способы обойти это, но суть в том, что, поскольку ITime - это интерфейс без подписи индекса, вы не можете назначить его интерфейсу с подписью индекса, например MixinDescriptor. Это поведение известные и в настоящее время предполагаемые. Самый простой способ справиться с этим - заменить ITime с interface на type.

Наконец, ваш миксин может нуждаться в исправлении, поскольку ваша реализация функции time() ссылается на переменную с именем chance, которая, похоже, не определена. Я предполагаю, что код выдает ошибку во время выполнения, но, возможно, вы не включили весь соответствующий код или это просто пример. Принимая код за чистую монету, может быть, вместо chance вам следует использовать this (и сохранить TypeScript счастливым, используя Параметр this с типом Chance)? Нравиться

function time(this: Chance.Chance) {
  const h = this.hour({ twentyfour: true });
  const m = this.minute();
  return `${h}:${m}`;
};

Во всяком случае, это самое близкое к ответу, которое я могу дать без установки ChanceJS. Надеюсь, это укажет вам правильное направление. Удачи!

Спасибо за отличный ответ. Я согласен, что лучшим решением было бы обновить типизацию, но я не совсем уверен, где нужно изменить типизацию, чтобы исправить это. Я все еще изучаю TypeScript, я учусь, используя его каждый день и создавая на нем проекты. При этом ваше решение исправило множество ошибок компиляции. Теперь единственное, что я получаю только Error:(11, 32) TS2709: Cannot use namespace 'Chance' as a type., я предполагаю, это связано с тем, как построены типизации.

James W. Lane 08.05.2018 15:52

Может это Chance.Chance? Существует пространство имен Chance с интерфейсом Chance внутри него. Какой тип вы видите, когда проверяете объект, созданный с помощью new Chance()? Мне сложно отлаживать, если я не установлю эту библиотеку и ее типизацию, что я не в состоянии сделать прямо сейчас.

jcalz 08.05.2018 15:56
Chance.Chance исправил это!
James W. Lane 08.05.2018 15:58

@jcalz Ответ был мертв и решил проблему.

const chance = new Chance() as Chance.Chance & ITime;
chance.mixin(time as any); // no error
chance.time(); // no error

Теперь для библиотеки есть типы по умолчанию: npm i change @types/chance

import * as Chance from 'chance';
const digit: number = Chance.default().integer({ min: 0, max: 20});

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