在功能语言中,我可以定义一个方法,使签名清楚地表明该方法返回Type A或TypeB。例如:
class AppError(message: String)
public convertToString(input: Int) : Either[AppError, String]
左侧始终是不愉快的道路,右侧始终是不愉快的道路。我正在尝试在打字稿中做类似的事情。我写了这段代码
type AppError = {message: String, errorCode: number}
function doSomething(param1: number) : AppError | string {
if (param1 < 0) {
return {"message": "param1 cannot be less than 0"}
} else {
return +param1
}
}
const result3 = doSomething(-1)
if (typeof result3 === "AppError") {
console.log("got this exception" + result3.message)
} else
console.log("got result " + result3)
}
但是打字稿编译器说
This condition will always return 'false' since the types '"string" | "number" | "bigint" |
"boolean" | "symbol" | "undefined" | "object" | "function"' and '"AppError"' have no
overlap.ts(2367)
我用Google搜索,发现了this线程,但我仍然不明白为什么typeof x始终为假?如果您传递一个负数,我的代码将返回AppError对象,在这种情况下,typeof result3 === 'AppError'
的计算结果应为true。
答案 0 :(得分:1)
typeof
不返回类名或构造函数名,而仅返回 native JavaScript值类型名,仅 其中之一:
'string'
'number'
'bigint'
'boolean'
'symbol'
'undefined'
'object' // Note that `typeof aNullVar` evalutes to `'object'` btw.
'function'
您需要的是a TypeScript type guard function,它用于运行时类型检查,以使编译器将“信任”以强制执行类型安全。
请注意下面isAppError
的返回类型是value is AppError
。
像这样:
function isAppError( value: string | AppError ): value is AppError {
return typeof value === 'object'
&& ( value !== null )
&& ( 'message' in value )
&& ( 'errorCode' in value )
&& ( typeof (value as AppError).errorCode === 'number' );
}
此isAppError
函数可能可以简化(例如,如果您处于严格模式,则不需要value !=== null
检查。
并按如下方式使用:
if( isAppError( result3 ) ) {
// TypeScript *knows* that `result3` is of-type `AppError` inside this `if` statement's scope.
console.log( result3.errorCode ); // TypeScript knows that result3 is AppError here.
}
else {
// If `result3`'s type is an intersection type of only 2 types then TypeScript *knows& that result3 is of-type `string` inside this `else` statement's scope.
console.log( result3.substring(1) ); // TypeScript knows that result3 is string here.
}