通过传入构造函数检测类型的工作不一致

时间:2018-06-18 21:41:03

标签: typescript

我有一个" WTF"时刻。我有一个类型建模系统,它不仅可以利用Typescript systax进行设计时键入操作,还可以使用运行时。细节并不是非常重要,但基本上你定义了一个"模型"像这样:

@model({ dbOffset: "authenticated" })
export class Person extends Model {
  // prettier-ignore
  @property @length(20) public name: string;
  // prettier-ignore
  @property @min(1) @max(100) public age?: number;
  @property public gender?: "male" | "female" | "other";
  @property public scratchpad?: IDictionary;
  // prettier-ignore
  @property @pushKey public tags?: IDictionary<string>;

  // prettier-ignore
  @ownedBy(Person) @inverse("children") public motherId?: fk;
  // prettier-ignore
  @ownedBy(Person) @inverse("children") public fatherId?: fk;
  // prettier-ignore
  @hasMany(Person) public children?: IDictionary;

  @ownedBy(Company) public employerId?: fk;
}

使用 Person 类的这个实例获取META属性,该属性允许对其属性进行运行时内省。

我已经使用了这个课程进行了很多测试,而今天当我创建了 FancyPerson 时,我感到震惊和恐惧我发现它表现得与众不同以一种完全令人困惑的方式。这是FancyPerson:

@model({ dbOffset: "authenticated" })
export class FancyPerson extends Model {
  @property public name: string;
  @property public age: number;
  @property public phoneNumber: string;
  // prettier-ignore
  @property @mock("phoneNumber") public otherPhone: string;
  // prettier-ignore
  @property @mock(bespokeMock) public foobar: string;
  @ownedBy(Company) public employer: fk;
  @hasMany(Car) public cars: fk[];
}

现在,当您在下面添加新的记录时,我会在 FancyPerson 但不是时收到Typescript错误。错误是

  

[TS]   类型的参数&#39; {name:string;年龄:数量; }&#39;不能分配给&#39; Model&#39;类型的参数。     对象文字只能指定已知属性,而且名称&#39;类型&#39;模型&#39;中不存在。

enter image description here

enter image description here

好的,问题就是这个问题...... FancyPerson 拥有属性name,但出于某种原因我传入< strong> FancyPerson 它不会隐式输入 FancyPerson ,而只是默认值模型(确实不 em>拥有name属性。

这是Record的静态添加方法,我想可能是问题的根源:

public static async add<T extends Model>(
  model: new () => T,
  payload: T,
  options: IRecordOptions = {}
) {
  let r;
  try {
    r = Record.create(model, options);
    console.log(r.modelName, r.META.dbOffset);

    r._initialize(payload);
    await r._save();
  } catch (e) {
    const err = new Error(`Problem adding new Record: ${e.message}`);
    err.name = e.name !== "Error" ? e.name : "FireModel";
    throw e;
  }

  return r;
}

如果此问题的根源,我无法看到它如何与People一起使用,而不是FancyPeople。请有人从疯狂中解救出来。

更新

我一直疯狂地玩各种模型中的属性,以了解什么可能将Record.add()函数切换到远离识别传入的构造函数...

以下是我刚刚找到的内容,如果模型类中至少有一个属性 -required,则Record.add()会隐式识别该类,但如果全部属性是必需的然后它回退到默认值Model(这对于我正在做的事情并不好)。

这种行为是非常可重复的,但我不知道为什么它是这样的。感觉像个臭虫。

0 个答案:

没有答案