我有一个接受参数的TypeScript方法。参数可以是string
类型,也可以是Object
类型。当我在方法正文中对typeof
类型进行string
检查时,仍然会收到错误消息,指出在indexOf
类型上找不到substr
和string | Object
。
据我所知,if
块体应该由条件保护。我做错了什么?
function mergeUrlParameters(sourceParameters: string | Object, targetUrl: string, overwrite: boolean = false): string {
var sourceParamObject: Object;
if (typeof sourceParameters === "string") {
if (sourceParameters.indexOf("?") >= 0)
sourceParameters = sourceParameters.substr(sourceParameters.indexOf("?") + 1);
sourceParamObject = $.deparam(sourceParameters, true);
} else {
sourceParamObject = sourceParameters;
}
...
}
我正在使用安装了最新TypeScript的Visual Studio 2015(1.8.x)。
更新
事实证明,sourceParameters
变量的重新分配会导致类型保护失败。我发布了一个有关此行为的相关潜在错误报告here。与此同时,我可以使用几种简单的解决方法,我选择使用?
条件表达式内联检查和子串调用。
答案 0 :(得分:0)
您需要将其转换为适当的类型:
function mergeUrlParameters(sourceParameters: string | Object, targetUrl: string, overwrite: boolean = false): string {
var sourceParamObject: Object;
if (typeof sourceParameters === "string") {
if ((<string> sourceParameters).indexOf("?") >= 0) {
sourceParameters = (<string> sourceParameters).substr((<string> sourceParameters).indexOf("?") + 1);
}
sourceParamObject = $.deparam((<string> sourceParameters), true);
} else {
sourceParamObject = sourceParameters;
}
...
}
如果你想避免这种投射,你可以创建自己的类型保护(你的代码中没有):
function isString(x: any): x is string {
return typeof x === "string";
}
然后:
function mergeUrlParameters(sourceParameters: string | Object, targetUrl: string, overwrite: boolean = false): string {
var sourceParamObject: Object;
if (isString(sourceParameters)) {
if (sourceParameters.indexOf("?") >= 0) {
sourceParameters = sourceParameters.substr(sourceParameters.indexOf("?") + 1);
}
sourceParamObject = $.deparam(sourceParameters, true);
} else {
sourceParamObject = sourceParameters;
}
...
}
TypeScript Handbook | typeof type guards
中的更多信息好的,在玩了一段时间后,我了解你的代码编译器问题是什么 代码的这种变化编译时没有错误:
function mergeUrlParameters(sourceParameters: string | Object, targetUrl: string, overwrite: boolean = false): string {
var sourceParamObject: Object;
if (typeof sourceParameters === "string") {
sourceParamObject = $.deparam(sourceParameters.indexOf("?") >= 0 ?
sourceParameters.substr(sourceParameters.indexOf("?") + 1)
: sourceParameters
, true);
} else {
sourceParamObject = sourceParameters;
}
}
主要区别在于您在代码中将值重新分配给sourceParameters
,这可能会使编译器感到困惑。
为了说明这个问题,请考虑这个简单的例子:
function x(param: number | string): number {
var num: number;
if (typeof param === "string") {
num = parseInt(param);
} else {
num = param;
}
return num;
}
function y(param: number | string): number {
if (typeof param === "string") {
param = parseInt(param);
}
return param;
}
函数x
编译时没有错误,但y
出现以下错误:
Argument of type 'number | string' is not assignable to parameter of type 'string'. Type 'number' is not assignable to type 'string'
(在the playground中查看)