打字稿 - 嵌套,多类型断言

时间:2017-09-27 08:18:59

标签: typescript2.0 definitelytyped

我正在尝试研究如何做我认为会被称为'嵌套类型断言'的事情。

Typescript将允许您通过接口断言一个空对象,以构成接口的类型。例如:

const fakeRequest = <ExpressCore.Request>{ protocol: 'test-protocol' };

让我指定一个协议字段集的对象,它充当ExpressCore.Request类型(具有许多属性 - https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express-serve-static-core/index.d.ts#L177)。我可以方便地使用它来获取Request对象并对协议进行断言。

当我尝试使用更复杂的界面时,例如,为Request - https://github.com/request/request提供的界面 - 编译器告诉我必须提供三种内部类型:

Generictype 'RequestAPI<TRequest, TOptions, TUriUrl> requires 3 type argument(s).

我正在使用通过DefinitelyTyped提供的@ types / request类型。

在声明文件中,RequestAPI由以下内容定义:

export interface RequestAPI<TRequest extends Request, TOptions extends CoreOptions, TUriUrlOptions> {

在研究过这个之后,我找到了通过需要一个内部接口的接口来声明对象所需的语法示例:

const pos = <GeoJSON.Feature<GeoJSON.GeometryObject>>{
  "type": "Feature",
  "properties":{},
  "geometry": {
    "type": "Point",
    "coordinates": [0, 1]
  }
};

请参阅What means "Generic type 'Feature<T>' requires 1 type argument(s)" in Typescript?

但是,我不能通过三个内部接口来解决这个问题。以下尝试失败了:

const foo = { {} as request.Request, {} as request.CoreOptions, {} as request.RequiredUriUrl } as request.RequestAPI;

const fakeRequester = <request.RequestAPI<request.Request><request.CoreOptions><request.RequiredUriUrl>> {{}, {}, {}};

等。

如果有人知道如何处理嵌套的多重断言,或者可以指出我做错了什么,那就不胜感激了。

1 个答案:

答案 0 :(得分:1)

我必须阅读有关泛型类型参数的一些内容,但最终还是可行的。

要弄清楚发生了什么,我使用ts-node并构建了相互扩展的小接口以及将它们用作通用参数的其他接口。

最终我能够在我的测试中模拟Request对象;例如:

    const fn: (options: (request.CoreOptions & request.UriOptions), callback?: request.RequestCallback) => any =
        function(options: (request.CoreOptions & request.UriOptions), cb?: request.RequestCallback) {
            expect(options.uri).to.equal('http://foo/id-xyz');
            done();
            return <request.Request>{};
        };

    const fakeRequester = <request.RequestAPI<request.Request, request.CoreOptions, {}>>fn;

    const agent = _agent(fakeRequester);

    agent('http', '/foo/id-xyz', { 'Accept-Encoding': 'gzip' }, fakeWritable(), (err, result) => {});
});