如何用打字稿

时间:2020-04-12 03:19:32

标签: typescript

在功能语言中,我可以定义一个方法,使签名清楚地表明该方法返回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。

1 个答案:

答案 0 :(得分:1)

JavaScript和TypeScript中的

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.
}