Typescript 索引签名失败 Angular 个对象

Typescript index signature failure Angular objects

我有以下 angular 打字稿代码。

在函数 'blendBinA' 中不断出现错误:

"Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'ObjA'.ts(7053)"

如何解决?

interface ObjA {
    propA: string;
    propB: number;
    propC: string[];
}

public objA: ObjA = { propA: 'Henk', propB: 23, propC: ['singel 23'] };
public objB: any = { propX: '6445 GB', propA: 'henk' };

blendBinA() {
    for (const k in this.objB) {
        if (this.objA.hasOwnProperty(k)) {
            this.objA[k] = this.objB[k];
        }
    }
}

这是因为 this.objA.hasOwnProperty(k) 不像 type guard

您需要定义自己的自定义类型保护:

const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);

然后尝试:

interface ObjA {
  propA: string;
  propB: number;
  propC: string[];
}


const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);

class Foo {

  public objA: ObjA = { propA: 'Henk', propB: 23, propC: ['singel 23'] };
  public objB: any = { propX: '6445 GB', propA: 'henk' };

  blendBinA() {
    for (const k in this.objB) {
      if (hasProperty(this.objA, k)) {
        this.objA[k] = this.objB[k];
      }
    }
  }
}

Playground

如果可能,请尝试输入 objB

P.S。可以强制 hasOwnProperty 表现得像 typeguard:

看这个例子:

type Tag = { [prop: `tag${number}`]: never }

interface Object {
  hasOwnProperty(v: PropertyKey): boolean & Tag
}

interface CallableFunction extends Function {
  call<
    T,
    Prop extends string,
    R extends boolean & Tag
  >(this: (this: T, property: Prop) => R, thisArg: T, property: Prop): thisArg is T & Record<Prop, string>;
}

declare const obj: { name?: string, surname?: number }

if (Object.prototype.hasOwnProperty.call(obj, 'name')) {
  const test = obj.name // string
}

if (Object.prototype.propertyIsEnumerable.call(obj, 'name')) {
  const test = obj.name // string | undefined
}

Here你可以找到相关的问题和答案,并有更多的解释。

Here 你会在我的文章中找到一些例子