【问题标题】:typescript arrow function parameter type safe打字稿箭头函数参数类型安全
【发布时间】:2016-08-26 18:33:33
【问题描述】:

我的代码在 "noImplicitAny": false 时可以正常工作。

import ...;

@Injectable()
export class HeroService {
  private _cachedHeroes: Observable<Hero[]>; 
  private _init: boolean;
  private _heroesObserver: Observer<Hero[]>;
  private _heroObserver: Observer<Hero>;
  heroes$: Observable<Hero[]>; 
  hero$:   Observable<Hero>; 
  public _dataStore: { heroes: Hero[], hero: Hero };

  constructor (private http: Http) {
        this._init = true;
        this._dataStore = { heroes: [], hero: {_id: null, name: null} };
        this.heroes$ = new Observable((observer: any) =>  this._heroesObserver = observer).share();//.publishReplay(1).refCount();
        this.hero$   = new Observable((observer: any) =>  this._heroObserver = observer).share();
        this._baseUrl = 'http://localhost:8081/api/hero/';  
  }

  loadHero1(id: number) {
      this.hero$ = this._cachedHeroes.map(heroes => heroes.find(hero => {hero._id === id;})) 
                                     .catch(handleError)
                                     .subscribe( data => {  
                                                            this._dataStore.hero = data;
                                                            this._heroObserver.next(this._dataStore.hero);
                                                         },  
                                                  error => handleError('Could not load hero.')
                                               );
  }
  .......
}        

由于我想让它类型安全,我将 tsconfig.json 更改为 “noImplicitAny”:是的。

然后我得到以下错误

[0] services/hero.service.ts(58,7): error TS2322: Type 'Subscription' is not assignable to type 'Observable<Hero>'.
[0]   Property '_isScalar' is missing in type 'Subscription'.
[1] [BS] File changed: dist\services\hero.js
[1] [BS] File changed: dist\services\common.js
[0] services/hero.service.ts(58,65): error TS2345: Argument of type '(hero: Hero) => void' is not assignable to parameter of type '(value: Hero, index: number, obj: Hero[]) => boolean'.
[0]   Type 'void' is not assignable to type 'boolean'.

这是我的问题

  1. 如何将 this._cachedHeroes.map().subscribe() 从 Subscription 类型转换为 Observable 类型以解决 TS2322 错误?我试过&lt;Observable&lt;Hero[]&gt;&gt;.this._cachedHeroes....,但没用。
  2. 如何定义 TypeScript 箭头函数的参数类型以解决 TS2345 错误?我试过heroes.find( (hero: Hero) =&gt; {hero._id === id;}),但没用。
  3. 如何在下面的代码中将显式 any 更改为 Observer 类型?

    this.hero$ = new Observable((observer: any) => this._heroObserver = observer).share();

感谢任何建议。

【问题讨论】:

  • 你能标记hero.service.ts(58,65)吗?

标签: typescript angular


【解决方案1】:

subscribe() 返回 Subscription,而不是 Observable

如果您将 subscribe() 更改为 map() 它应该可以工作

  loadHero1(id: number) {
    this.hero$ = this._cachedHeroes
    .map(heroes => heroes.find(hero => {hero._id === id;})) 
    .catch(handleError)
    .map( data => {  
      this._dataStore.hero = data;
      this._heroObserver.next(this._dataStore.hero);
    });
  }

或者改变

heroes$: Observable<Hero[]>; 

heroes$: Subscription;

但我认为这不是您的代码的意图。

【讨论】:

  • 感谢您的快速响应。第二个 .map() 是否与 subscript() 方法具有相同的目的?我刚刚添加了第三个问题:) 会很快尝试你的答案。
  • 不,他们有不同的目的。 subscribe() 使 observable 执行,而 map() 不执行。 subscribe() 返回的Subscription 允许您使用subscr.unsubscribe() 取消订阅。如果您想从 observable 接收数据(例如我的答案中的代码),您需要先订阅 hero$.subscribe()&lt;div&gt;{{hero$ | async}}&lt;/div&gt;
  • 我将 subscribe() 更改为 map() 并得到一个不同的错误:[0] services/hero.service.ts(58,7): error TS2322: Type 'Observable'不可分配给类型 'Observable'。 [0] 类型“void”不可分配给类型“Hero”。有什么想法吗?
  • 我不知道 TS 泛型(我自己只使用 Dart)。你可以试试this._dataStore.hero = &lt;Observable&lt;Hero&gt;&gt;data;
  • 我试过了。它会给出一个新的错误。我可以使用(数据:英雄),它不会给出错误,但它不会解决 [0] 类型“void”不可分配给类型“英雄”。
【解决方案2】:

在@Günter Zöchbauer 的帮助下,我把这件事弄清楚了。所以添加 return 语句将解决类型不匹配。这是通过编译器检查的修改代码。

  loadHero1(id: number) {
      this.hero$ = this._cachedHeroes.map(heroes => heroes.find(hero => { return hero._id === id; } )) 
                                     .catch(handleError)
                                     .map( (data : Hero) => {  
                                                            this._dataStore.hero = data;
                                                            this._heroObserver.next(this._dataStore.hero);
                                                            return data;
                                                         } 
                                                  //error => handleError('Could not load hero.')
                                               );
  }

【讨论】:

    猜你喜欢
    • 2022-07-27
    • 2017-01-04
    • 2020-05-28
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多