TypeScriptはなぜ "Like "型を使うのか?
質問
TypeScriptにはなぜ型があり、さらに"like type"があるのでしょうか?例として
Promise<T>
と
PromiseLike<T>
.
この2つのタイプの違いは何ですか?どのような場合に使用するのでしょうか?この場合、なぜ1つの
Promise
タイプにすればいいのでは?
どのように解決するのですか?
定義ファイルを見てみると(仮に lib.es6.d.ts を例にとります) を見れば、かなりわかりやすいと思います。
例えば ArrayLike インタフェースがあります。
interface ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
}
は 配列 よりも制限されています。
interface Array<T> {
length: number;
toString(): string;
toLocaleString(): string;
push(...items: T[]): number;
pop(): T | undefined;
concat(...items: T[][]): T[];
concat(...items: (T | T[])[]): T[];
join(separator?: string): string;
reverse(): T[];
shift(): T | undefined;
slice(start?: number, end?: number): T[];
sort(compareFn?: (a: T, b: T) => number): this;
splice(start: number, deleteCount?: number): T[];
splice(start: number, deleteCount: number, ...items: T[]): T[];
unshift(...items: T[]): number;
indexOf(searchElement: T, fromIndex?: number): number;
lastIndexOf(searchElement: T, fromIndex?: number): number;
// lots of other methods such as every, forEach, map, etc
[n: number]: T;
}
こんな関数が欲しいかもしれないので、2つを分けておくと良いですね。
function getSize(arr: Array<any>): number {
return arr.length;
}
console.log(getSize([1, 2, 3])); // works
でも、これではうまくいきません。
function fn() {
console.log(getSize(arguments)); // error
}
このようなエラーになります。
IArguments' 型の引数は、'any[]' 型のパラメータに代入できません。 any[]' に割り当てられません。
タイプ 'IArguments' にプロパティ 'push' がありません。
でも、こうすればどちらも動きます。
function getSize(arr: ArrayLike<any>): number {
return arr.length;
}
(さらに MDN の ArrayLike )
と同じように
Promise
と
PromiseLike
の実装にこだわらないライブラリを作っているのであれば、 この
Promise
を使うのであれば、このようなことをする代わりに
function doSomething(promise: Promise<any>) { ... }
こうする
function doSomething(promise: PromiseLike<any>) { ... }
そうすれば、私のライブラリのユーザが別の実装(bluebird)を使っていても、問題なく動作します。
の定義にお気づきでしょうか? Promise はこうなっています。
declare var Promise: PromiseConstructor;
これは非常に特殊なもので、他の実装では異なるプロパティ、例えば異なるプロトタイプを持つかもしれません。
interface PromiseConstructor {
readonly prototype: Promise<any>;
...
}
というのが主な理由でしょうか。
PromiseLike
がサポートされる前に、いくつかの実装が利用可能だったことです (例えば
ブルーバード
,
約束/A+(プラス
,
jQuery
など)。
typescriptがこれらの実装を使用しているコードベースで動作するためには、以下のようなタイプでなければなりません。
Promise
でなければならず、そうでなければ多くの矛盾が生じます。
関連
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] なぜGoogleはJSONレスポンスにwhile(1);を前置するのでしょうか?
-
[解決済み] event.preventDefault() vs. return false
-
[解決済み] 2つのJavaScriptオブジェクトのプロパティを動的にマージするにはどうすればよいですか?
-
[解決済み] どのラジオボタンが選択されているかをjQueryで知るにはどうしたらよいですか?
-
[解決済み] jQueryで要素にスクロールする
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] varキーワードの目的と、どのような場合に使用する(または省略する)べきですか?
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
-
[解決済み] これは純関数ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScriptで次の要素/前の要素を取得しますか?
-
[解決済み] javascriptで2つの数値を連結する方法は?
-
[解決済み] 文字列がすべて同じ部分文字列で構成されているかどうかを調べるにはどうすればよいですか?
-
[解決済み] React js 親コンポーネントから子コンポーネントの状態を変更する
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
-
[解決済み] 文字列がhtmlであるかどうかをチェックする
-
[解決済み] javascriptで文字列から関数を作成する方法はありますか?
-
[解決済み] AJAX Mailchimp サインアップフォームの統合
-
[解決済み] Chromeのwebkitインスペクタで「Unsafe JavaScript attempt to access frame with URL...」というエラーが継続的に発生する。
-
[解決済み] Chrome拡張機能:popup.htmlを強制終了させる