在 Angular 中转换 BehaviourSubjects 时出错

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

假设我们有两个接口:

interface A {
  name: string;
  _id?: string;
}

interface B {
  name: string;
  _id: string;
}

当将它们分配给彼此时,打字稿的行为就像我所期望的那样:

const a: A = { name: 'a' };
const b: B = { name: 'b', _id: '1' };
const c: B = a; // Type A is not assignable to type B
const d: A = b;

const getA = (): A => {
  return b;
};

在第 3 行中,我收到以下错误:

TS2322: Type A is not assignable to type B
Types of property _id are incompatible.
 Type string | undefined is not assignable to type string
  Type undefined is not assignable to type string

这是有道理的,因为

_id
a
可能是未定义的。

当我将 A 与 BehaviourSubject 一起使用时,我也收到错误:

const behA = new BehaviorSubject<A>(a);
const behB = new BehaviorSubject<B>(b);

const getBehA = (): BehaviorSubject<A> => {
  return behB;
}
S2322: Type BehaviorSubject<B> is not assignable to type BehaviorSubject<A>
Types of property observers are incompatible.
 Type Observer<B>[] is not assignable to type Observer<A>[]
  Type Observer<B> is not assignable to type Observer<A>
   Type A is not assignable to type B
    Types of property _id are incompatible.
     Type string | undefined is not assignable to type string
      Type undefined is not assignable to type string

对我来说,不太清楚为什么。如果我尝试使用简单的容器接口进行相同的操作,效果很好:

interface Container<T> {
  value: T;
}

const cB: Container<B> = {
  value: {
    name: 'name',
    _id: '1234',
  },
};

const getCA = (): Container<A> => {
  return cB;
}
angular typescript
1个回答
0
投票

正如错误所说:

Application bundle generation failed. [3.140 seconds]

✘ [ERROR] TS2322: Type 'ASD<B>' is not assignable to type 'ASD<A>'.
  Types of property 'observers' are incompatible.
    Type 'Observer<B>[]' is not assignable to type 'Observer<A>[]'.
      Type 'Observer<B>' is not assignable to type 'Observer<A>'.
        Type 'A' is not assignable to type 'B'.
          Types of property '_id' are incompatible.
            Type 'string | undefined' is not assignable to type 'string'.
              Type 'undefined' is not assignable to type 'string'. [plugin angular-compiler]

    src/main.ts:37:2:
      37 │   return behB;
         ╵   ~~~~~~

行为主体将完美映射,但它会扩展

Subject

export declare class BehaviorSubject<T> extends Subject<T> {
  private _value;
  constructor(_value: T);
  get value(): T;
  getValue(): T;
  next(value: T): void;
}

但这是由于

observers
Observer<T>
(
extends Subject<T>
) 的数组,因此这里类型检查无法检查从
Subject<T>
继承的属性上的各个属性:

export declare class Subject<T> extends Observable<T> implements SubscriptionLike {
    closed: boolean;
    private currentObservers;
    /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
    observers: Observer<T>;
    /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
    isStopped: boolean;
    /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */
    hasError: boolean;
    ...

内部

observers
next
属性给出了错误:

export interface Observer<T> {
  next: (value: T) => void;
  ...

因此,类型检查在回调级别时不起作用,因此您可能会遇到这个问题。我不知道具体原因,但这是我的分析。

参考Stackblitz

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