在 TypeScript 中构建 Chance Mixin

问题描述 投票:0回答:2

我正在开发 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'.
typescript typescript-typings definitelytyped
2个回答
6
投票

看起来 ChanceJS 的 DefinitelyTyped 定义并不真正支持你想要做的事情。对此的理想解决方案是更改这些类型,但假设您不想这样做,类型断言将是您的朋友。

我没有安装 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
 这样具有索引签名的接口。这是一种“已知且当前预期的”行为。最简单的处理方法可能是将 
ITimeinterface
 更改为 
type
最后,您的 mixin 可能需要修复,因为您的 
time()

函数实现引用了一个名为

chance

 的变量,该变量似乎未定义。我想代码在运行时会抛出错误,但也许您没有包含所有相关代码或者它只是一个示例。从表面上看代码,也许您应该使用 
chance
 而不是 
this
(并通过使用类型为 
this
Chance
 参数
来让 TypeScript 满意)?喜欢
function time(this: Chance.Chance) {
  const h = this.hour({ twentyfour: true });
  const m = this.minute();
  return `${h}:${m}`;
};

无论如何,这是我在不安装 ChanceJS 的情况下可以给出的最接近的答案。希望它能为您指明正确的方向。祝你好运!
    

我的实现方式如下。我的 mixins 使用通用代码库来生成模拟,因此我将其包含在此处。

0
投票
定义常用mixins接口,如果你不打算使用它,请忽略它。

interface Mock_I<T> { id?: number depth?: number models?: string[] ensure?: string[] skip?: string[] data?: T }

为每个 mixin 定义选项:
// example of a model that uses this mock
interface ProfileModelBasedMockParamsI extends Mock_I<ProfileModel> {
  notation?: string // let's just say time has this optional param
}

// simple as question asked
interface TimeMockParamsI {
  notation?: string // let's just say time has this optional param
}

现在使用 mixin 扩展 opportunity 并创建一个新的接口来代替 Chance.Chance 接口:
interface ChanceMixins extends Chance.Chance {
  time(options: TimeMockParamsI): any
  // ... more mixins here as needed
}

然后最后使用它(如果您还没有添加机会类型,请执行
yarn add -D @types/chance
添加机会类型):

import Chance from 'chance';
const chance = new Chance() as Chance.Chance & ChanceMixins;

chance.time(); // should work with no issues
chance.time('24'); // should work with no issues


© www.soinside.com 2019 - 2024. All rights reserved.