使功能接口异步,而无需复制和粘贴

时间:2019-03-26 12:58:38

标签: typescript webpack webpack-loader

Webpack提供用于实现加载程序的TypeScript接口:

import { loader } from "webpack";

namespace loader {
  interface Loader extends Function {
      (this: LoaderContext, source: string | Buffer, sourceMap?: RawSourceMap): string | Buffer | void | undefined;
      pitch?(remainingRequest: string, precedingRequest: string, data: any): any;
      raw?: boolean;
  }
}

所以当我实现它的时候

const sfcLoader: loader.Loader = function(source: string) {
  /* ... */
};

现在,我正在尝试创建一个是那个接口但返回Promise的接口:

const sfcLoader /* : loader.Loader */ = async function(source: string) {
  /* await ... */
};

请注意,async

我当然不想复制并粘贴该界面。是否可以通过webpack扩展(或其他方式)并修改界面?

1 个答案:

答案 0 :(得分:0)

您需要基于加载程序接口创建映射类型。这个想法是,您需要使用关键字infer来访问该函数的现有返回类型。我想,您需要将返回类型包装到Promise中。在TypeScript Playground中尝试以下代码示例(我们为“ TypeScript Quickly”一书编写了该示例):

type ReturnPromise<T> =
    T extends (...args: infer A) => infer R ? (...args: A) => Promise<R> : T;   

type Promisify<T> = {
    [P in keyof T]: ReturnPromise<T[P]>;
};

interface SyncService {
    baseUrl: string; 
    getA(): string;
}

class AsyncService implements Promisify<SyncService> {
    baseUrl: string; 

    getA(): Promise<string> {
        return Promise.resolve('');
    }
}

let service = new AsyncService();


let result = service.getA(); // hover over result: it's of type Promise<string>

在这里,我们声明一个新的类型Promisify<T>。为了测试它,我们使用接口SyncService,找到它的方法属性(在这种情况下为getA()),并将其返回类型包装到Promise中。