質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

2751閲覧

typescriptでPromise<boolean | { ...}>を扱う

koyamaso

総合スコア8

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

1グッド

0クリップ

投稿2018/09/01 20:14

前提・実現したいこと

anyを使わずに

typescript

1Promise<boolean | { 2 service: string; 3 username: string; 4 password: string; 5}>

で返ってくる値を扱いたい

該当のソースコード

typescript

1const credentials : any = await Keychain.getGenericPassword(); 2/* 3 4function getGenericPassword(options?: Keychain.Options | undefined): Promise<boolean | { 5 service: string; 6 username: string; 7 password: string; 8}> 9*/

試したこと

typescript

1type Credentials = boolean | { 2 service: string; 3 username: string; 4 password: string; 5} 6const credentials : Credentials = await Keychain.getGenericPassword(); 7this.setState({ 8 username: credentials.username, 9 password: credentials.password, 10}) 11/* 12[ts] 13Property 'username' does not exist on type 'Credentials'. 14 Property 'username' does not exist on type 'false'. 15any 16*/ 17 18

補足情報(FW/ツールのバージョンなど)

typescript 3.0.1

x_x👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

コンパイルエラーの原因

[ts]

Property 'username' does not exist on type 'Credentials'.
Property 'username' does not exist on type 'false'.
any

コンパイルエラーの内容を和訳すると

プロパティ 'username' は型 'Credentials' に存在しません。 プロパティ 'username' は型 'false' に存在しません。

となっています。

つまり、Credentialsboolean型(false)の可能性があり、boolean型の場合にはusernameプロパティが存在しないためコンパイルエラーになるということです。

解決方法

usernameプロパティを使う段階で、変数credentialsboolean型ではないことを示せば良いです。

TypeScript

1interface Credentials { 2 service: string; 3 username: string; 4 password: string; 5} 6 7type CredentialsOrBoolean = Credentials | boolean; 8 9function isBoolean(value: any): value is boolean { 10 return typeof value === "boolean"; 11} 12 13namespace Keychain { 14 export interface Options { 15 // 省略 16 } 17 export function getGenericPassword(options?: Keychain.Options): Promise<CredentialsOrBoolean>{ 18 // 省略 19 } 20} 21 22(async () => { 23 24 const credentials: CredentialsOrBoolean = await Keychain.getGenericPassword(); 25 if (isBoolean(credentials)) { 26 // 何らかの処理 27 return; 28 } 29 30 // isBooleanを通過することで型推論によって 31 // 変数 credentials が CredentialsOrBoolean型 から 32 // boolean型 を含まない Credentials型 に変わる 33 this.setState({ 34 username: credentials.username, 35 password: credentials.password, 36 }); 37 38})();

コードを分かりやすくするために

  • boolean型を含まないインターフェースCredentials型
  • boolean型を含む型エイリアスCredentialsOrBoolean型

を分けて定義しています。
また、変数がboolean型か判定するためのisBoolean関数を定義しています。

await getGenericPassword の戻り値の時点では、変数credentialsCredentialsOrBoolean型です。

そのため、isBoolean関数による判定で、boolean型の場合は処理を先に進ませないようにします。
すると、型推論によって変数credentialsCredentialsOrBoolean型からCredentials型に変わります。

変数credentialsCredentials型になったことでcredentials.usernamecredentials.passwordでコンパイルエラーが発生しなくなります。

なお、上記はあくまでサンプルなので、変数credentialstruefalseの場合で分岐する必要がある場合には、isBoolean関数による判定の箇所のコードを置き換えて実装してください。

投稿2018/09/02 06:09

crsh

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koyamaso

2018/09/02 12:36

無事解決しました! 分かりやすい解説をありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問