TypeScript 参数类型是多种类型的联合:如何确定提供的类型并使用它?

Pet*_*ter 4 typescript reactjs typeguards

我正在使用TypeScript 中的React Google Login库。它具有 TypeScript 的类型绑定,但所有示例都是 JavaScript 语言,而且我对 TypeScript 还很陌生。

设置代码如下所示:

  <GoogleLogin
    clientId="client-id-value"
    onSuccess={successResponseGoogle}
    onFailure={failureResponseGoogle}
    cookiePolicy={'single_host_origin'}
  />
Run Code Online (Sandbox Code Playgroud)

在 TypeScript 中,onSuccess 回调的签名是:

readonly onSuccess: (response: GoogleLoginResponse | GoogleLoginResponseOffline) => void
Run Code Online (Sandbox Code Playgroud)

GoogleLoginResponseOffline类型只有一个属性 ,code其中GoogleLoginResponse具有一系列属性来访问经过身份验证的用户的详细信息。

我遇到的问题是 TypeScript 不允许我访问响应参数上的任何 GoogleLoginResponse 属性,例如

“GoogleLoginResponseOffline 类型上不存在属性‘getBasicProfile’”

我已尝试以下方法来转换或检查参数的类型,但都给出了一种或另一种类型的错误。我的函数如下所示:

const responseGoogleSuccess = (response: GoogleLoginResponse|GoogleLoginResponseOffline) => {

  // Tried to check for property to identify type
  if(response.googleId){    // Property 'googleId' does not exist on type 'GoogleLoginResponseOffline'
      const profile = response.getBasicProfile();  // Property 'getBasicProfile' does not exist on type 'GoogleLoginResponseOffline'
  }

  // Tried to cast like this
  const typedResponse = <GoogleLoginResponse>response;

  // Tried to check type
  if(response instanceof GoogleLoginResponse){   // 'GoogleLoginResponse' only refers to a type, but is being used as a value here.
  }
}
Run Code Online (Sandbox Code Playgroud)

从TypeScript 文档来看,似乎if(response instanceof GoogleLoginResponse)很接近,但在这种情况下失败了,因为GoogleLoginResponse它是一个接口,并且它需要是一个类。

请告诉我这是如何做到的!我查看了很多具有类似标题的 StackOverflow 问题,但没有一个涵盖这一点。

Ale*_* L. 5

您可以使用in运算符来缩小类型

\n\n
\n

对于n in x表达式,其中n是字符串文字或字符串文字类型,x是联合类型,\xe2\x80\x9ctrue\xe2\x80\x9d 分支缩小为具有可选或必需属性 的类型n,而 \xe2\x80 \x9cfalse\xe2\x80\x9d 分支缩小为具有可选或缺失属性的类型n

\n
\n\n
const responseGoogleSuccess = (response: GoogleLoginResponse | GoogleLoginResponseOffline) => {\n  if(\'googleId\' in response) {\n      const profile = response.getBasicProfile(); // response is of type GoogleLoginResponse here\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

操场

\n\n
\n\n

您当然可以定义自定义类型保护,但in在这种情况下使用运算符要容易得多。但是,如果您在多个地方需要它,则可以这样定义类型保护:

\n\n
type Reposense = GoogleLoginResponse | GoogleLoginResponseOffline;\n\nconst responseGoogleSuccess = (response: Reposense) => {\n  if (isLoginResponse(response)) {\n    const profile = response.getBasicProfile();\n  }\n}\n\nconst isLoginResponse = (response: Reposense): response is GoogleLoginResponse =>\n  \'googleId\' in response;\n
Run Code Online (Sandbox Code Playgroud)\n\n

操场

\n