我有这个界面:
interface IParameters {
form: number;
field: string;
...
}
我希望form
属性为数字或函数,field
为字符串或函数。
我尝试这样的事情:
interface IParameters {
form: number | Function;
field: string | Function;
...
}
我需要这个,因为在我的代码中我使用这样的变量:
var form = (typeof _oParameters.form === "function" ? _oParameters.form() : _oParameters.form);
var field = (typeof _oParameters.field === "function" ? _oParameters.field() : _oParameters.field);
我不想在我的所有代码中将此变量从字符串/数字更改为默认函数,并防止将此变量设置为其他类型。
但如果我尝试像函数一样调用这两个变量之一:
var param:IParameters;
param.form();
...
我收到此错误:
无法调用类型缺少调用签名的表达式。
但param.form = 12;
有效。
我找到的唯一解决方案是将form
和field
声明为any
类型。
是否有其他方式来定义此变量而没有any
类型?
答案 0 :(得分:3)
也许如果您使用呼叫签名而不是Function
来定义联合类型,就像这样......
interface IParameters {
// form is of type function that returns number, or number literal.
form: () => number | number;
// field is of type function that returns a string, or string literal.
field: () => string | string;
}
class Foo {
constructor (param: IParameters) {
var x = typeof param.form === "number" ? param.form : param.form();
var y = typeof param.field === "string" ? param.field : param.field();
}
}
在这里,我仍然使用form
检查field
和typeof
,但是TypeScript很高兴它可以是函数调用或值。
答案 1 :(得分:3)
如果您尝试使用seriesOne中的代码,您会注意到,您无法为form
(或field
)分配非函数值。
你会得到一个
Type '{ form: string; }' is not assignable to type 'IParameters'.
Types of property 'form' are incompatible.
Type 'string' is not assignable to type '() => string'.
我发现使用form: (() => string) | string;
可以解决此问题。
您可以在the typescript playground处尝试代码。
工作样本:
interface IParameters {
form: (() => string) | string;
}
function strFunct(): string {
return 'Hello TypeScript';
}
function test() {
let paramA: IParameters = {
form: strFunct
}
let paramB: IParameters = {
form: 'Hello stackoverflow'
}
}
class Foo {
constructor(param: IParameters) {
var x = typeof param.form === 'string' ? param.form : param.form();
}
}
答案 2 :(得分:1)
<强> UPD 强>
使用TypeScript,这种行为似乎是个问题#3812
根据指定的里程碑,它将作为TypeScript 2.0的一部分进行修复。
原始回答
你可以使用instanceof
作为类型保护,如
var field = (_oParameters.field instanceof Function ? _oParameters.field() : _oParameters.field);