我目前正在将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中实例化一个有很多或所有可选属性的类型对象的正确方法是什么。
什么是正确的方法?
答案 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") { }
//
}