Я работаю над 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'.






Похоже, что Определения определенного типа для 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. Надеюсь, это укажет вам правильное направление. Удачи!
Может это Chance.Chance? Существует пространство имен Chance с интерфейсом Chance внутри него. Какой тип вы видите, когда проверяете объект, созданный с помощью new Chance()? Мне сложно отлаживать, если я не установлю эту библиотеку и ее типизацию, что я не в состоянии сделать прямо сейчас.
Chance.Chance исправил это!
@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});
Спасибо за отличный ответ. Я согласен, что лучшим решением было бы обновить типизацию, но я не совсем уверен, где нужно изменить типизацию, чтобы исправить это. Я все еще изучаю TypeScript, я учусь, используя его каждый день и создавая на нем проекты. При этом ваше решение исправило множество ошибок компиляции. Теперь единственное, что я получаю только
Error:(11, 32) TS2709: Cannot use namespace 'Chance' as a type., я предполагаю, это связано с тем, как построены типизации.