2017-05-01 45 views
13

なぜタイプスクリプトにタイプがあり、次に「タイプ」がありますか?この例は、Promise<T>PromiseLike<T>です。これら2つのタイプの違いは何ですか?いつそれらを使うべきですか?この場合、なぜ1つしかないのですかPromiseタイプですか?typescriptで "Like"タイプが使用されるのはなぜですか?

+0

ArrayとArrayLikeオブジェクトについて質問したら、どう答えますか、それらの違いは何ですか? – Thomas

+1

[libの定義](https://github.com/Microsoft/TypeScript/blob/master/lib/lib.es6.d.ts#L1323)を見ましたか? –

+0

リンクありがとうございます。定義された型を見ることは良いことですが、この質問はインタフェースだけでなく、2つの型の意味の違いに焦点を当てています。これらの2つのタイプを定義する目的は何ですか?なぜ作者がそれを選んだのですか?私は@Thomasはここに直交API設計の意味があることを暗示していると思います。彼らは何ですか?これらのより大きな設計上の質問の一部をカバーする答えは、私が後にしていることです。あなたが好きなら、私は質問の文言を更新することができます。 – Stewart

答えて

16

定義ファイル(lib.es6.d.tsとしましょう)を見れば、それはかなり簡単です。

たとえばArrayLikeインタフェース:

interface ArrayLike<T> { 
    readonly length: number; 
    readonly [n: number]: T; 
} 

Array 1よりも制限されています。

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 
} 

それは、このエラーで結果:

Argument of type 'IArguments' is not assignable to parameter of type 'any[]'.
Property 'push' is missing in type 'IArguments'.

しかし、私はこれを行う場合の両方が動作します(ArrayLike in MDNの詳細)

function getSize(arr: ArrayLike<any>): number { 
    return arr.length; 
} 

同じPromiseとし、 PromiseLike、もし私がimplemについて意見がないその後、Promiseの代わりに、このことのentation:マイライブラリのユーザは、それだけで動作します異なる実装(青い鳥)を使用している場合でも、その後

function doSomething(promise: PromiseLike<any>) { ... } 

function doSomething(promise: Promise<any>) { ... } 

は、私はこれをやります良い。それは非常に具体的になり

declare var Promise: PromiseConstructor; 

、他の実装が異なる特性を持っているかもしれません、例えば異なるプロトタイプ:あなたはPromiseの定義はこれがわかります場合

interface PromiseConstructor { 
    readonly prototype: Promise<any>; 

    ... 
} 

私は私たちがPromiseLikeを持っている主な理由は、ネイティブサポートがサポートされる前にいくつかの実装が利用可能であったということです(例えば、bluebirdPromises/A+jQuery、およびそれ以上)。
typescriptがこれらの実装を使用しているコードベースで動作するためには、Promise以外の型が必要です。そうしないと多くの矛盾が生じます。

+0

偉大な答えですが、この特殊なケースで私はまだ混乱しています。なぜPromiseLikeに 'catch()'を置くのが問題なのですか? – rekire

+0

@rekire「PromiseLike」に 'then'だけを含める理由を知りませんでしたが、いくつかの約束の実装には' catch'がありません(例えば、[Promises/A +](https: //promisesaplus.com/)はしません)。 –

関連する問題