Home>

Without any

Promise<boolean | {
    service: string;
    username: string;
    password: string;
}>


I want to handle the value returned by

Applicable source code
const credentials: any = await Keychain.getGenericPassword ();
/ *
function getGenericPassword (options ?: Keychain.Options | undefined): Promise<boolean | {
    service: string;
    username: string;
    password: string;
}>
*/
Tried
type Credentials = boolean | {
  service: string;
  username: string;
  password: string;
}
const credentials: Credentials = await Keychain.getGenericPassword ();
this.setState ({
      username: credentials.username,
      password: credentials.password,
})
/ *
[ts]
Property 'username' does not exist on type 'Credentials'.
  Property 'username' does not exist on type 'false'.
any
*/
Supplemental information (FW/tool version etc.)

typescript 3.0.1

  • Answer # 1

    Cause of compilation error

      

    [ts]
      Property'username'does not exist on type'Credentials&apos ;.
      Property'username'does not exist on type'false&apos ;.
      any

    Translating compile errors into Japanese

    Property 'username' does not exist for type 'Credentials'.
    Property 'username' does not exist for type 'false'.

    That is,Credentialsmay beboolean type (false), and if it isboolean type,username< This means that there is a compile error because the/code>property does not exist.

    Solution

    At the stage of using theusernameproperty, you can show that the variablecredentialsis not of typeboolean.

    interface Credentials {
        service: string;
        username: string;
        password: string;
    }
    type CredentialsOrBoolean = Credentials | boolean;
    function isBoolean (value: any): value is boolean {
      return typeof value === "boolean";
    }
    namespace Keychain {
        export interface Options {
            // omitted
        }
        export function getGenericPassword (options ?: Keychain.Options): Promise<CredentialsOrBoolean>{
            // omitted
        }
    }
    (async () =>{
        const credentials: CredentialsOrBoolean = await Keychain.getGenericPassword ();
        if (isBoolean (credentials)) {
            // do something
            return;
        }
        // By type inference by passing through isBoolean
        // The variable credentials is from CredentialsOrBoolean type
        // change to Credentials type without boolean type
        this.setState ({
            username: credentials.username,
            password: credentials.password,
        });
    }) ();

    To make the code easier to understand

    Interface withoutbooleanCredentials

    Type alias containingbooleanCredentialsOrBoolean

    is defined separately.
    It also defines aisBooleanfunction to determine if the variable is aboolean type.

    As of the return value of

    await getGenericPassword, the variablecredentialsisCredentialsOrBoolean.

    Therefore, in the judgment by theisBooleanfunction, in the case ofboolean type, the processing is not allowed to proceed.
    Then, the variablecredentialschanges fromCredentialsOrBoolean typetoCredentials typeby type inference.

    Compile withcredentials.usernameorcredentials.passwordbecause the variablecredentialsis nowCredentialsThe error will not occur.

    The above is just a sample, so if you need to branch if the variablecredentialsistrueorfalse, Please implement by replacing the code of the judgment byisBooleanfunction.