2017-04-08 32 views
1

如果用户忽略了类成员属性的默认值,是否有任何方法?如果省略,可能会让TypeScript类的可选属性回到默认值?

我有constains另一个类的可选实例的自定义类:

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,所以有时一些成员变量Children子可不确定。在这些情况下,我希望MyClass1构造函数启动新的MyClass2()classInstance成员变量。

我这是怎么分配创建MyClass1的实例:

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

因为Children子被忽略,我认为它会在构造函数中设置的默认值。然而,这种情况并非如此。我也尝试从classInstance -variable中删除可选符号,但这会产生编译错误,因为此时对象必须与MyClass1的结构相匹配。我想我不设法通过转换错误编译,但它并没有解决这个问题(虽然我不知道这是否正确编译其一):

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

在两宗个案中,Children子得到默认值构造函数设置,它出来null/undefined。

对于我来说,如何解决铸造问题(无论是设置属性可选还是使用铸造)并不重要,只要我可以控制默认值即可。

回答

1

这里的问题是

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

这里是MyClass1实例。 TypeScript类型系统被认为是普通对象是MyClass1实例。

它将被转录到var myNewClass = { name: "MyClass" }MyClass1类没有实例化。故事的结局。

做预期的事情的正确方法是从JSON向类构造函数提供值。考虑到对象属性(classInstance)可以是undefined,类属性不能依靠默认值等constructor({ classInstance = new MyClass2 }) { ... },应该手动分配:

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专为值未定义),配方可以进行修改,以使用由语言提供的权力:

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 
}); 
+0

这样一个完整的答案,谢谢!我只是想问一下这个问题:'const {title =“”,classInstance = new MyClass2} = jsonMyClass1;'这个语法做了什么?这是否意味着第一个标题和classInstance被分配了值,那么jsonMyClass1中的字段会覆盖可用的值?但是,如果创建了一个对象,只需在下一行输入'this.title = title;',如何访问这些变量?我对语法有点困惑,我从未见过它。你声明const变量,这就是我所理解的,但我不明白它是一个对象还是单独的变量? –

+0

不客气。这是[解构](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)。它创建'title'和'classInstance'临时变量,它是为var提供默认值的最简洁的方式(如果prop不存在于jsonMyClass1对象或未定义的)。另一种方法是编写像'this.classInstance = jsonMyClass1.classInstance!== undefined? jsonMyClass1.classInstance:新的Class2'。你可以随时查看它在http://www.typescriptlang.org/play/上的转换,这是一个学习TS的好方法。 – estus

+0

谢谢!嗯,我遇到了另一个有关构造函数的问题:如果classInstance是MyClass1会怎么样?我该如何确保数据通过嵌套子类的构造函数传递? 例如,JSON来通过包含: '{名字:“在主级MyClass1的实例”,Children子是:{title:“MyClass1的实例嵌套”}}' 我怎样才能确保也MyClass1的嵌套被创建与构造函数?我从json收到整个对象,所以在这种情况下我是否可以控制它的创建方式? –

相关问题