示例代码:在 angular2 中制作模拟

sample code: making mocks in angular2

我正在学习 Angular2。 在 DI 页面中,有用于模拟的示例代码。 https://angular.io/docs/ts/latest/guide/dependency-injection.html

什么意思

let mockService = <HeroService> {getHeroes: () => expectedHeroes }

看起来像是从 HeroService 函数定义 mockService 函数。

什么是<HeroService><HeroService> 正在选角吗?

let expectedHeroes = [{name: 'A'}, {name: 'B'}]
let mockService = <HeroService> {getHeroes: () => expectedHeroes }

it('should have heroes when HeroListComponent created', () => {
  let hlc = new HeroListComponent(mockService);
  expect(hlc.heroes.length).toEqual(expectedHeroes.length);
});

在JavaScript和TypeScript中,{a: b}是一个对象字面量。它定义了一个对象,其中 属性 a 的值为 b.

所以

{getHeroes: () => expectedHeroes }

是一个对象属性,名为getHeroes,其值为() => expectedHeroes() => expectedHeroes。因此,该值是一个不带参数 (()) 并返回值 expectedHeroes.

的函数

<HeroService> 被称为 type assertion:

Sometimes you’ll end up in a situation where you’ll know more about a value than TypeScript does. Usually this will happen when you know the type of some entity could be more specific than its current type.

Type assertions are a way to tell the compiler “trust me, I know what I’m doing.” A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler.

添加到 并对代码背后的推理给出一些解释。

TypeScript 使用 Structural Type System1。这意味着如果它像鸭子一样嘎嘎叫,那么它就可以被认为是鸭子(或者更准确地说,与鸭子兼容)。举个例子

class Duck {
  quack() { }
}

let duck = {
  quack: () => {}
}

因为 duck 有一个 quack 方法,你可以把它传递给任何需要 Duck 的东西,比如

function doQuack(duck: Duck) {
  duck.quack();
}

doQuack(duck);

TypeScript 足够聪明,知道 duck 对象字面量可以被视为 Duck,即使我们实际上从未使用 duck = new Duck() 创建 Duck 的实例.这是因为duck的结构足以与Duck类型兼容,因为它匹配结构;该结构只有一个 quack 方法。

如果我们尝试将 duck 键入为 Duck,而我们没有 quack 方法,那么我们会遇到编译错误。

let duck: Duck = {   // compile error
  mooo: () => {}
};

let duck: Duck = {
  quack: () => {}    // OK
}

也就是说,对于你的例子,HeroSerivce 有两种方法,一种是获取所有英雄,一种是通过 id 获取英雄。

class HeroService {
  getHeroes(): Hero[] { .. }
  getHeroById(id: number): Hero { .. }
}

还有一个 HeroComponent 和一个接受 HeroService

的构造函数
class HeroComponent {
  constructor(heroService: HeroService) {}
}

现在如果我们尝试通过以下

let mockService = { getHeroes: () => expectedHeroes }

HeroComponent构造函数,我们会得到一个编译错误,因为mockServiceHeroService结构不匹配.它只有一个 getHeroes 方法,而结构实际上由 两个 方法组成,getHeroesgetHero.

所以为了强制编译器只接受它,我们 "cast" 它到 <HeroService>

我们可以传递以下内容(没有 "casting")并且它会起作用,因为它与结构匹配。

let mockService = {
  getHeroes: () => expectedHeroes,
  getHero: (id: number) => null
};

1 - 从 TypeScript 文档章节阅读更多内容 Type Compatibility