-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
type エイリアスと interface の使い分けについて #790
Comments
@version-1 「ほかの言語にある型とインタフェースと同じ使い分けをする」というのは具体的にどのような使い分けをイメージされているのでしょうか?例に挙げてくださったプログラミング言語Java、PHP、Goなどで型エイリアスとインターフェースがあり、それらの使い分けについて示したドキュメントもありましたら共有いただけると議論の材料になると思います。 |
勘違いしていたところあり、 type エイリアスは具象型に近いものかと思っていたのですが、インターフェースなどの 抽象型に近いと理解しました。 https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases
「要求されたプロパティが実装されれば動く」というのが interface だけの機能かと思っていたのですが、下記のようなケースで type エイリアスでも問題なく動作するとわかったのでインターフェースに近いと考えました。
これを踏まえて議論の論点を訂正させていただければと思います。 |
具体的な使い分けについて(訂正後)1. それぞれの使い分けの結論に対する記述について
といった内容がありますが、ドキュメントを読む限り公式等も「型エイリアスがどうしても必要な場合(Union Type や primitve な型にエイリアスをつけたい場合など)をのぞいて interface を使うのが望ましい」のではないかと思っており、本ドキュメントもそのように修正を検討した方が良いと思うのですがどうでしょうか? 本ドキュメントで触れている Google のスタイルガイド でも、
となっている様ですし、現TypeScritptのドキュメントでも同様の項目
となっている様なので、特段理由がなければ interface を使っていれば問題ないといった姿勢になっているように見えます。 2. 同項目使いわけのルールを統一する際についての記述
上記と関連しますが、 interface 側に倒す様なある中で型エイリアス側に倒す例を挙げているのが読んでいて腑に落ちない点がありました。本ドキュメントがある程度TypeScriptエントリーレベルの読者を想定しているのであれば、「型エイリアスがどうしても必要な場合(Union Type や primitve な型にエイリアスをつけたい場合など)をのぞいて interface を使うのが望ましい」という姿勢を勧めるのが優しい様な気がします。 3. 該当のページの構成についてこちらは色々な意見や他ページとの平仄の問題などあるかと思いますが、 a. 違いを説明 のような構成になっているものを a. 使い分けを説明 反転させることを検討しても良いのではと思います。 後者のメリットとしては、例えば
といったものが考えられます。 これは主観的かもしれませんが「TypeScript 違い」として検索した場合に違い自体を知りたいというよりその「使い分け」を知りたい場合が多いかと思うので構成を見直しても良いのかなと思っております。 |
これについてもう少し詳しく教えて頂きたいです!
|
お忙しい中対応ありがとうございます。 1. なぜそのほうが初心者に優しいと思うのか?色々と調べていく中で、interface側に倒す方が良いというような記事等に触れることが多く、初学者がわざわざそれに反する選択をする必要はないと考えたからです。 記事中で引用しているスタイルガイドでも、 interface 側に倒すことが紹介されていたり(前コメントで私が引用した部分)、スタイルガイド内で紹介されている記事 でも
といった引用があります。「type エイリアスしか適用できないケース以外は interface を使うべき」といった主張が多く見受けられるようですし、技術的に両方適用できる場面では interface 側にメリットがあると書かれているように思います。(最新のバージョンで改善されている等、見落としている部分があれば別ですが・・) こういった主張を検討せずに初学者が type エイリアスを使う方に統一する理由がイマイチ見当たらないと考えます。 2. もし下記を書き直すとしたら、どういう表現にしたいのか?冒頭で両者の使い分けに答えはないと言っているので、両方の立場を書いたのかと推測しているのですが、前段で上記のような
となっていたので、当記事だけ見ると型エイリアスを使う理由が判然としないと感じました。 個人的な意見としては、上に書いたような
といったような構成になると良いと思っております。 現状のように、両方の立場を紹介する場合は、型エイリアスを使う根拠を紹介したり「一方」などのワードを使って対立を明確にすると読みやすくなるかとも思っています。 |
@version-1 こちらは、執筆する時にも記述をどうするか非常に悩んでおりました。 @version-1 さんのご主張も最もだと思っておりまして、どちらが良いという話のコメントではないですが、自分が今の記述をした背景を議論の参考に書かせて頂きます。🙆🏻♂️
Googleスタイルガイドやその他の記事などでもインタフェースを使うべきという主張は多く見受けられるのですが、最新のTypeScriptの公式ドキュメントでは
と書かれており、自分はこの記述から「どちらかを使うかは利用者の好みです」と解釈をしておりました。 ドキュメントとしてスタイルを明確に主張するべきか悩んだ結果、インタフェースを優先して利用するべきかはプロジェクトごとに決めるべきスタイルガイドであり、そのスタイルガイドを今回のドキュメントでそうあるべきと記述するのは少し混乱を招くかな?と思っておりました。 例えば、ReactではPropsの型を定義するときに慣例として型エイリアスが利用されますが、Googleのスタイルガイド等に従って、「Interfaceを優先的に使いましょう」と書いた場合に初学者はなぜReactのPropsの型定義はInterfaceを使わないんだ?という疑問が生まれて余計な混乱が生じてしまうかなということを懸念していました。 以上のことと公式ドキュメントの記述を踏まえて、当時は「正解はありません」と書いていました。🙆🏻♂️ |
質問内容
type エイリアスと interface の使い分けについて
https://typescriptbook.jp/reference/object-oriented/interface/interface-vs-type-alias#%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%81%A8%E5%9E%8B%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9%E3%81%AE%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91
リンクの箇所に
といった内容がありますが、TypeScript から離れて一般的に インターフェースと型の概念自体は異なっており、TypeScript でも同様で他の言語と同様に型とインターフェースを使い分けるべきかと思うのですがいかがでしょうか?
自身の理解の確認の意味もございますので、詳細ご確認いただき返答頂けると幸いです。
詳細
Java, Go, PHP 等を念頭においたインターフェースの概念自体、私の理解ではダックタイピングを念頭においており、「使う側から最低限これだけのプロパティ・メソッドが実装されていれば良い」というのを示すものだと考えています。
一方、型自体はより具象的な型を示すためインタフェースを使う際のユースケースとは違い「まさにこのモジュールを動かすにはその具象的な型の全てのプロパティや型が必要」といったことを示す違いがあり、使い分けについては上記に書いた Java, Go, PHP と同様に使い分けられるべきだと考えています。
また、少し古いドキュメントにはなるかと思いますが、「TypeScript における interface とは何か?」の説明として、個人的に一番しっくり来るのがこちらのドキュメントの冒頭の記述になります。
https://www.typescriptlang.org/docs/handbook/interfaces.html
One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.
以上を踏まえて、型とインタフェースの使い分けの大枠として、その「ほかの言語にある型とインタフェースと同じ使い分けをする」といった説明で良いのかと思います。(実際のドキュメントではそれぞれの違いを説明する必要もあるかとは思いますけど)
補足
プルリクで編集の提案をしようかとも思ったのですが、注意書きにもあるようにあらかじめ合意を得る必要がありそうなのと自分の理解を確認させていただきたかったので issue を立たさせていただきました。
上記自分の理解に抜け漏れなどなければ、編集プルリクエストも送らせていただきたいと考えております。
こちらのドキュメントも含めていて、typeエイリアス で interface で「ぞれぞれできること」は示しているのですが「そもそもの型とインタフェースの違い」についてはあまり書かれていない印象なのでその辺り改善できればと思っています(本ドキュメントでの言及はありますがあらかじめ使い分けやそれぞれの概念の違いに触れてからの方が「できること」の内容もハラオチしやすいように思っております。)
https://www.typescriptlang.org/docs/
The text was updated successfully, but these errors were encountered: