Создание шанса Mixin в TypeScript - PullRequest
0 голосов
/ 07 мая 2018

Я работаю над ChanceJS mixin , который я планирую распространять через 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'.

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

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

const chance = new Chance() as Chance.Chance & ITime;
chance.mixin(time as any); // no error
chance.time(); // no error
0 голосов
/ 08 мая 2018

Похоже, что определения DefinitiveTyped для 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, поскольку именно это делает функция mixin. Это позволит скомпилировать строку 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. Надеюсь, это направит вас в правильном направлении. Удачи!

...