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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

TypeScript

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

Q&A

2回答

4480閲覧

Vue.jsでのUnion Typesの型チェック

eeengineeeeeeer

総合スコア15

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

TypeScript

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

0グッド

0クリップ

投稿2019/01/10 03:30

編集2022/01/12 10:55

typescript

1// type.ts 2 3export interface Fruits { 4 id?: number 5 type: Apple | AppleJam 6} 7 8export interface Apple { 9 rank: number 10 area: string 11 comment: string 12} 13 14export interface AppleJam { 15 area: string 16 comment: string 17}

vue

1<template> 2<!-- 省略 --> 3</template> 4 5<script lang="ts"> 6import { Component, Prop, Vue } from 'nuxt-property-decorator' 7import { Fruits } from './type.ts' 8 9@Component 10export default class AppleItem extends Vue { 11 @Prop() fruitsData!: Fruits 12 13 hoge() { 14 this.fruitsData.type.rank = 1 15 } 16} 17</script> 18

上記のコードの場合に、this.fruitsData.type.rankでエラーが発生します。

Property 'rank' does not exist on type 'Apple | AppleJam'. Property 'rank' does not exist on type 'AppleJam'.

これはinterface AppleJamの中にrankがないためにエラーが発生してるかと思うのですが、このコンポーネントにpropで値を受け取った段階で既にtypeがAppleであることが決まっているので、それを定義したいのですが、書き方がわかりません、、。propで受け取ったオブジェクトの中の型チェックはどのようにやるのでしょうか?

初学者のため、どなたかご教示お願いします。

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

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

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

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

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

papinianus

2019/01/10 03:42 編集

Appleインターフェイスをimportして、propの型アノテーションをFruitsではなく、Appleにしていない理由は?
eeengineeeeeeer

2019/01/10 03:50

fruitsDataには`id`が含まれたFruitsの型の形式でデータを受け取りたいからです。
guest

回答2

0

TypeScriptは詳しくないのですが、インターフェイス設計に興味があったので参考としての見解を。

設計の問題だという点では、7Kreuz様に同意します。

ただ、やりたいことからすると

interface Idetifiable { id : string } interface Apple { rank : number area: string } interface AppleJam { area: string } class AppleItem { prop: Identifiable & Apple } class AppleJamItem { prop: Identifiable & AppleJam }

こうなんじゃないかなと思いました。

型をもたせているのに、型チェックというのは変な気がします。型が静的に解決できていません。

このコンポーネントにpropで値を受け取った段階で既にtypeがAppleであることが決まっている

という文面はクラスの名前(AppleItem)に照らしても一貫した設計なのだとは思いますが、それをコード上表明しなければ、anyにして、idとrankをもっているか(動的に)型チェックするのと近い状態に陥っているように思えました。

投稿2019/01/10 05:16

papinianus

総合スコア12705

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

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

papinianus

2019/01/10 05:18

もちろん、交差型を使うとprop.id, prop.rank, prop.areaとなります。
guest

0

propsに渡す型の指定方法というより、型の設計の問題だと思います。FruitsをAppleとAppleJamに分け(従来のAppleとAppleJamをそれぞれAppleInfo、AppleJamInfoとします)、AppleItemコンポーネントが受け取るpropsの型はAppleにするべきでしょう。

下記のイメージです。

typescript

1interface AppleInfo { 2 rank: number 3 area: string 4 comment: string 5} 6interface AppleJamInfo { 7 area: string 8 comment: string 9} 10export interface Apple { 11 id?: number; 12 info: AppleInfo; 13} 14export interface AppleJam { 15 id?: number; 16 info: AppleJamInfo; 17} 18export type Fruits = Apple | AppleJam

補足:typeとされていたキー名をinfoに変更していますが、そちらのほうが意味として適当と思ったからです。もとのままでもコード上は問題ありません。

投稿2019/01/10 04:25

編集2019/01/10 04:28
7Kreuz

総合スコア112

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問