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

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

新規登録して質問してみよう
ただいま回答率
85.47%
型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

TypeScript

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

Q&A

解決済

1回答

382閲覧

親クラスと同じ名前のプロパティを上書きし、新たな型を与えたいです。

honamin

総合スコア5

型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

TypeScript

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

0グッド

0クリップ

投稿2023/09/19 09:14

編集2023/09/19 09:18

実現したいこと

Aクラスを継承するBクラスがあり、protected _params という同じ名前の内容の違うオブジェクトを持っています。Bでそのオブジェクトをオーバーライドし、型アサーションをしたのですが、Bの _paramsの型がAParamsから変更できません。

該当のソースコード

typescript

1type AParams = { 2 name: string, 3 age: number, 4 fuga: string; 5}; 6 7class A { 8 protected _params: AParams = { 9 name: "A", 10 age: 12, 11 fuga: 'AA' 12 }; 13} 14 15type BParams = AParams & { 16 name: string, 17 age: number, 18 hoge: number; 19}; 20 21class B extends A { 22 constructor() { 23 super(); 24 25 this._params = { 26 ...this._params, 27 name: "B", 28 age: 12, 29 hoge: 1 30 } as BParams; 31 } 32}

エラーメッセージ

クラスBの this._params は、AParams のままです。(vscode, typescript 5.2.2)

試したこと

PT3.5の提案も以下のものを試しましたがだめでした。

typescript

1//1. 2(this._params as BParams) = { 3...this._params, 4name: "B", 5age: 12, 6hoge: 1 7} 8 9//2. 10this._params = { 11...this._params, 12name: "B", 13age: 12, 14hoge: 1 15} as Bparams 16 17//3. 18this._params = { 19super["_params"], 20name: "B", 21age: 12, 22hoge: 1 23}

よろしくお願いします。

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

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

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

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

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

honamin

2023/09/19 09:15

コードが見辛くなってしまい、申し訳ございません。
honey32

2023/09/19 10:48

失礼します。 そもそも「protected _params プロパティを持つ A と、それを継承した A を作る」こと自体がチグハグな印象を受けます。 差し支えなければ、どのようなメソッド・関数を実装するためにこのようなクラスを作ろうとされているのかも共有していただけると考える材料になるかもしれません。
honamin

2023/09/19 10:55

質問ありがとうございます。 未熟なもので、おかしなことを書いているかもしれませんが、申し訳ありません。 class Aがまずあり、それを class Bが継承します。 class Bは A とほぼ同じ機能を持っていますが、少しだけ高機能で、パラメータの種類が増えます。 ここで、Aのもつ _params を引き継ぐ語ちでBでオーバーライドして使いたいです。 しかしオーバーライドしても型を変更できませんので質問いたしました。
honamin

2023/09/19 11:01

class Aのパラメータは、this._paramsA 、 class B のパラーメータは this._paramsB と、名前を別にして、class Bでは this._paramsB = { ...this._paramsA, newPropA: 1, newPropB: 2, } とすれば、期待通りなのですが、これだと、class Bは2つパラメータの(_paramsAと_paramsB)を持つことになってしまいます。できれば同じ名前の _params で、継承する側が親の同名のプロパティを上書きする形にしたいと考えています。 上書き自体はできるのですが、なぜか型が替えられません(Aの_paramsのままになる)
honey32

2023/09/19 11:40

その「パラメータ」と呼ばれているものについて、それはどこで読み書きされることを目的とされていますか? 外部から読み書きしたいだけなら ```typescript interface WithParams<P> { params: P } ``` のようなインターフェスを A, B それぞれが実装するだけで住むと思いますが、protected ということは、クラス内で使用されるということですよね?
honamin

2023/09/19 11:48

親クラスAの_params: APrams プロパティに、継承するBクラスが、新しいkeyを追加してそれをBparamsとしたいのですが、それがどうやってやるのかわからないという質問です。
guest

回答1

0

ベストアンサー

とりあえずこのようにすれば書けそうです。

ts

1type AParams = { 2 name: string, 3 age: number, 4 fuga: string; 5}; 6 7class A { 8 // B から使うには、一度 static (またはクラスの外の変数)に入れる必要がある 9 static defaultParams: AParams = { 10 name: "A", 11 age: 12, 12 fuga: 'AA' 13 } 14 15 protected _params: AParams = { 16 ...A.defaultParams, 17 } 18} 19 20class B extends A { 21 // B 側でもう一度 _params プロパティを宣言しなおす必要がある 22 // (override は必須ではないが、名前間違いをチェックしてくれる) 23 protected override _params: AParams & { hoge: number; } 24 25 constructor() { 26 super(); 27 28 this._params = { 29 ...A.defaultParams, 30 name: "B", 31 age: 12, 32 hoge: 1, 33 } 34 } 35 36 printSelf() { 37 console.log(JSON.stringify(this._params)) 38 } 39} 40 41

TypeScript Playground でホバーして色々試せます。

https://www.typescriptlang.org/play?#code/C4TwDgpgBAggCgQwE4ILYGcoF4oG8oAWA9gOYQBcU6wSAlgHYlQC+AUKwMYA2C6mMeVlCgB6EVABCUQNIMgSIZA-vKAxBkDWDIHsGQIAMgADlAZXpVgCYLQ5RAEP+A-BkD6DKsD1DIEuGQJ0MgOwZAaJqPAkJqAHU0CQ-8sCmioBiGQGiGQFH9QEDIwBkGQCEGQKE9AyMoABMIADMEAFcuYEQUDEp4ZDRMHFxY4WIySgAiCogq2LZYsCQiYAgONsSoAH0wQrzYHKLsQWFhADpJmHHktMzs-vQAGgbWRu5eTCkIAA82+kT+UdFxKUAXBUBzBkAghkUdHr7czEB1hkBbhkBFhkAxhkBihkAkhkBi7UAAFGAdQZAFYMgCkGQCaDGEojFhGIoAAKIgANwgSDoySgqmCgAgMi6qEGAEQZwupALAqgFklQDJqYBVBMJP0AgwyAcoZAMMM1iBgDMGQDyDEEAJRNFptDoQLootEY6C9Rb5IYYKAAMjwUBS6RICEo9HSqAARmiWOxhBwiPRqEh0h0iEgETzjsJ0OlIJaeQBufVjYAEWjocaSx4jUpjMaTcbTWYZLIy5ZlMbK1WUABMKwDbGEjWEzQYwAAyhAuCkrTaoIbjUQuBBxlxSAiAFKZgDyADlxiaGCRaCkQAj3Z7vQ8ijy+Sm1uxWEA

投稿2023/09/19 12:17

honey32

総合スコア169

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

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

honamin

2023/09/20 05:51 編集

回答ありがとうございます。また、Playgroundというものを教えてくださって助かります。 「親クラスのプロパティを継承しつつ上書きする」というのは一般的な手法だと思っていましたが、回答を見ると、想像以上に複雑で、根本的に自分の認識が間違っているとおもい、よく確認してみたら、クラスBは親のプロパティを持てるだけで、上書きできていませんでした。 長々と質問にお付き合いくださり、ありがとうございます。
honamin
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問