为什么打字稿使用"喜欢"类型?

Ste*_*art 34 javascript types promise typescript

为什么打字稿有一个类型,然后是"喜欢类型"?这方面的一个例子是Promise<T>PromiseLike<T>.这两种类型有什么区别?我应该什么时候使用它们?在这种情况下,为什么不只是一种Promise类型?

Nit*_*mer 38

如果你看一下定义文件(让我们来看看lib.es6.d.ts),那就非常简单了.

例如ArrayLike接口:

interface ArrayLike<T> {
    readonly length: number;
    readonly [n: number]: T;
}
Run Code Online (Sandbox Code Playgroud)

阵列更有限:

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;
}
Run Code Online (Sandbox Code Playgroud)

将两者分开是很好的,因为我可能希望有这样的函数:

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

console.log(getSize([1, 2, 3])); // works
Run Code Online (Sandbox Code Playgroud)

但它不适用于此:

function fn() {
    console.log(getSize(arguments)); // error
}
Run Code Online (Sandbox Code Playgroud)

它导致此错误:

类型'IArguments'的参数不能分配给'any []'类型的参数.
'IArguments'类型中缺少属性'push'.

但如果我这样做,两者都会奏效:

function getSize(arr: ArrayLike<any>): number {
    return arr.length;
}
Run Code Online (Sandbox Code Playgroud)

(更多关于MDN中的ArrayLike)

PromisePromiseLike我一样,如果我正在构建一个不关心当时的实现的库,Promise而不是这样做:

function doSomething(promise: Promise<any>) { ... }
Run Code Online (Sandbox Code Playgroud)

我会这样做的:

function doSomething(promise: PromiseLike<any>) { ... }
Run Code Online (Sandbox Code Playgroud)

然后即使我的库的用户使用不同的实现(蓝鸟)它也会正常工作.

如果您注意到Promise的定义是这样的:

declare var Promise: PromiseConstructor;
Run Code Online (Sandbox Code Playgroud)

这使得它非常具体,其他实现可能具有不同的属性,例如不同的原型:

interface PromiseConstructor {
    readonly prototype: Promise<any>;

    ...
}
Run Code Online (Sandbox Code Playgroud)

我想我们的主要原因PromiseLike是在支持本机之前有几个实现可用(例如bluebird,Promises/A +,jQuery等).
为了使打字稿与使用这些实现的代码库一起工作,必须有一个类型以外的类型Promise,否则会有很多矛盾.

  • @rekire 我不知道他们为什么选择在 `PromiseLike` 中只包含 `then`,但我的猜测是一些 Promise 实现没有 `catch`(例如它看起来像 [Promises/A+](https:/ /promisesaplus.com/) 不)。 (4认同)