使用可选属性

时间:2016-08-10 19:29:13

标签: javascript typescript casting

我目前正在将JavaScript模块迁移到TypeScript,并且在强烈键入具有可选属性的对象时遇到问题。

示例很简单:

我有一个打开模态的方法。该方法有一个参数,它是模态的不同选项的映射,并且都是可选的。

与JavaScript一样:

openConfirmDialog({text : "are you sure ?"});
openConfirmDialog({title : "Confirmation required", confirmAction : noop});

等等。

迁移到TypeScript,我声明了一个代表所有这些不同选项的类:

class ConfirmDialogOptions {

    text : string;
    title : string;

    confirmAction : () => any;
    cancelAction  : () => any;

}

但是在尝试像普通JavaScript中那样实例化这个类:

let confirmOptions : ConfirmDialogOptions = { text : "are you sure ?" };

编译器引发错误:

  

初始化类型不能分配给变量类型ConfirmDialogOptions

我不得不使用:

强制进行类型转换
let a : ConfirmDialogOptions = {text: "lala"} as ConfirmDialogOptions;

这很有用,但好像有点像过热,全局让我想知道在TypeScript中实例化一个有很多或所有可选属性的类型对象的正确方法是什么。

什么是正确的方法?

3 个答案:

答案 0 :(得分:2)

而不是类声明具有optional properties的接口:

interface ConfirmDialogOptions {

    text ?: string;
    title ?: string;

    confirmAction ?: () => any;
    cancelAction  ?: () => any;

}

答案 1 :(得分:0)

您希望使用的是TypeScripts interface feature,您可以将其应用于自由浮动对象:

interface ConfirmDialogOptions {
  text?: string;
  title?: string;
  confirmAction?: () => any;
  cancelAction?: () => any;
}

class并没有做你认为它做的事情......它实际上是ES6 feature,它充当了围绕着香草JavaScript函数的糖。

// ES6 Class
class Person {
    constructor(name) {
      this.name = name;
    }
}

// Equivalent JS
var Person = (function () {
    function Person(name) {
        this.name = name;
    }
    return Person;
}());

由于您定义了class TypeScript,因此假设您希望ConfirmDialogOptions匹配new ConfirmationDialogOptions(...)来自{ text: 'hello' }来电的实例,这不是等效类型使用像kwargs这样的vanilla JavaScript对象。

答案 2 :(得分:0)

您可以通过使用问号

选择参数来实现此目的
class ConfirmDialogOptions {    
   text ?: string;
   title ?: string;
   //
}

或者更好的方法来声明类变量在构造函数

class ConfirmDialogOptions {    
    constructor(private text?:string, private title?: string) {  }\
    //
}

另一种解决方案是为参数提供默认值

class ConfirmDialogOptions {    
    constructor(private text:string="Default text", private title: string="Default title") {  }
    //
}