javascript - TypeScript:如何从对象初始化派生类?

标签 javascript typescript deserialization

我有以下代码:

class MyClass {
    name: string = "myname";
    constructor(public action: string) { }
}

let obj1: MyClass = { action: "act1" };

它无法编译。最后一行的错误是:

Property 'name' is missing in type '{ action: string; }' but required in type 'MyClass'.

我期待的是,因为“name”属性有一个默认值,所以我不会为 obj1 指定它。但事实并非如此。另外,似乎最后一行甚至没有调用 ctor,因此它不是 ctor 语法糖,而是完全不同的初始化调用。有没有办法可以为某些属性设置默认值并避免在此技术中初始化它们?

最佳答案

当你写下:

let obj1: MyClass = { action: "act1"};

您正在使用类 MyClass 作为类型,即您告诉编译器变量 obj1 符合MyClass 类型。它必须具有类的所有强制字段,并且不能具有任何未知的属性。

这很好,因为例如,如果类型有 200 个属性,智能感知可以提示您缺少属性。

现在,MyClass 实际上是一个,因此它不仅仅充当类型/接口(interface)。它还具有一些功能,即您可以调用构造函数,并且可以在声明类时使用 extends

现在,类的默认属性不是该类型的默认属性。如果您尝试在 typescript interfacetype 中添加初始值设定项,您将看到错误;相反,当您向类添加默认属性时,这意味着实例仅在从构造函数调用时才会将该属性初始化为默认值。

因此,您可以采取一些措施来解决该问题:

  1. 在这种情况下,您可以继续使用 MyClass 作为类型,但您仍然需要在对象文字中声明 name 属性:

let obj1: MyClass = {action: "act1", name: "first"};

如果你这样做,你仍然会面临:

Object literal may only specify known properties

因为MyClass中不存在action属性。您需要向 MyClass 添加一个 action 属性。

  • 使用构造函数
  • let obj1 = new MyClass("act1");

    虽然在某些情况下您可以有充分的理由使用类作为类型/接口(interface),但您可能应该在可能的情况下调用类构造函数(如本例所示),或者,正如注释所建议的那样,为此使用接口(interface)。

    在这种情况下,我认为您应该更喜欢调用构造函数。

  • 如果您只需要该类型来对变量类型进行编译器检查/智能感知,则可以使用接口(interface):
  • interface MyCustomType {
      name: string;
      action?: string;
    }
    

    因此,如果您尝试将变量键入为 MyCustomType 但不带名称,则会收到警告:

    let obj: MyCustomType = {
      action: 'act1',
    } // error, you need to set 'name' since it is a mandatory field
    

    您可以设置带有或不带有操作的对象,因为它是可选的(由于声明中的“?”)。

    您不能添加未知字段:

    let obj: MyCustomType = {
      name: 'name',
      value: 1, // error, unknown field
    }
    

    关于javascript - TypeScript:如何从对象初始化派生类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58525507/

    相关文章:

    javascript - JQuery - 切换类/添加类/删除类

    javascript - 类型错误 : Cannot read property of undefined when I call a method from an Imported Class [TypeScript]

    javascript - typescript 说: "types ' "a "' and ' "b "' have no overlap".是什么意思?

    java - 在我的代码中找不到 java.io.OptionalDataException 的原因

    c# - 如何从存储在 CouchDB 中的 Serilog 中反序列化 LogEvents

    javascript - Ajax调用MVC后将链接列添加到DataTable

    javascript - 将数据传递到基于组件的 mat-stepper 中的下一步

    javascript - 无法获取div的宽度

    typescript :如何解释扩展和函数类型之间的这种交互

    java - 如何使用对象字段本身给定的格式解析输入对象日期字段