如果省略,是否可以让TypeScript类的可选属性恢复为默认值? [英] Possible to have TypeScript class optional properties fall back to default value if omitted?

查看:306
本文介绍了如果省略,是否可以让TypeScript类的可选属性恢复为默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果用户忽略了类成员属性的默认值,是否可以通过任何方式为其分配值?

Is there any way to assign the class member properties default values if they are omitted by the user?

我有一个自定义类,该类包含另一个的可选实例类:

I have a custom class that constains an optional instance of another class:

export class MyClass1 {
    constructor() {
        this.name = "";
        this.classInstance = new MyClass2();
    }
    name: string;           // name of the object
    classInstance?: MyClass2;
}

class MyClass2 {
    constructor() {
        this.name = "MyClass2 initial name";
    }

    name: string;
}

MyClass1 的内容来自JSON,因此有些时候成员变量 classInstance 可能是不确定的。在这些情况下,我希望 MyClass1 构造函数将 new MyClass2()初始化为 classInstance 成员变量。

The content for MyClass1 comes from JSON, so some sometimes the member variable classInstance can be undefined. In these cases I'd like the MyClass1 constructor to initiate new MyClass2() into classInstance member variable.

这是我分配创建MyClass1实例的方式:

This is how I assign create the instance of MyClass1:

let myNewClass: MyClass1 = {
    name: "MyClass"
}

因为 classInstance ,我假设它将在构造函数中设置默认值。然而,这种情况并非如此。我还尝试从 classInstance -变量中删除可选符号,但这会产生编译错误,因为该对象必须与 MyClass1 的结构匹配。我想我可以通过强制转换成功地进行编译,但是没有解决问题(尽管我不确定该编译是否正确):

Because the classInstance is omitted, I assumed it would have the default value set in the constructor. However, this is not the case. I also tried removing the optional sign from the classInstance-variable, but this gives a compilation error because then the object has to match the structure of MyClass1. I guess I managed to compile without errors by casting, but it didn't solve the problem (although I'm not sure if this compiled properly either):

let myNewClass: MyClass1 = {
    name: "MyClass"
} as MyClass1

在任何情况下 classInstance 都没有获得构造函数设置的默认值,结果为null / undefined。

In neither case did classInstance get the default value that the constructor sets, it came out null/undefined.

对我来说,只要能够控制默认值,铸造问题的解决方式(设置属性为可选属性还是使用铸造)都无所谓。

For me it doesn't matter how the casting problem is solved (whether to set properties optional or use casting), as long as I have control over the default values.

推荐答案

这里的问题是

let myNewClass: MyClass1 = {
    name: "MyClass"
} as MyClass1

这是 not MyClass1 实例。 TypeScript类型系统被欺骗,以为普通对​​象是 MyClass1 实例。

here is not MyClass1 instance. TypeScript type system was 'cheated' to think that plain object is MyClass1 instance.

它将被转换为 var myNewClass = {名称: MyClass} MyClass1 类未实例化。故事的结尾。

It will be transpiled to var myNewClass = { name: "MyClass" }. MyClass1 class isn't instantiated. End of the story.

要做预期的事情的正确方法是将值从JSON提供给类构造函数。考虑到对象属性( classInstance )可能是未定义,因此类属性不能依赖于 constructor({classInstance = new MyClass2}){...} ,应手动分配:

The proper recipe to do the expected thing is providing values from JSON to class constructor. Considering that object properties (classInstance) can be undefined, class properties can't rely on default values like constructor({ classInstance = new MyClass2 }) { ... } and should be assigned manually:

export class MyClass1 {
    constructor(jsonMyClass1: MyClass1 = {}) {
        const { name, classInstance } = jsonMyClass1;
        this.name = 'name' in jsonMyClass1 ? name : "";
        this.classInstance = 'classInstance' in jsonMyClass1 ? classInstance : new MyClass2;
    }
    name: string;
    classInstance?: MyClass2;
}

let myNewClass: MyClass1 = new MyClass1({
    name: "MyClass"
});

在提供和处理数据时,考虑到类的使用方式(例如,使用 null 仅用于未定义的值),可以修改配方以使用该语言提供的功能:

When data is supplied and processed with how it will be consumed by the classes in mind (i.e. using null exclusively for values that are not defined), the recipe can be modified to use the powers offered by the language:

export class MyClass1 {
  constructor(jsonMyClass1: MyClass1 = {} as MyClass1) {
        const { name = "", classInstance = new MyClass2 } = jsonMyClass1;
        this.name = name;
        this.classInstance = classInstance;
    }
    name: string;
    classInstance: MyClass2;
}

let myNewClass: MyClass1 = new MyClass1({
    name: "MyClass",
    classInstance: null
});

这篇关于如果省略,是否可以让TypeScript类的可选属性恢复为默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆