对于不兼容的承诺返回,TypeScript不会引发错误

时间:2017-03-09 20:05:19

标签: typescript

我正在研究一种通用API调用方法,该方法允许使用者传递一个请求回调,该回调应返回一个解析为指定<T>有效负载(即Action)的promise。归结为这样的事情:

interface MyAction { type: string, value: string; }

declare function call<T>(request: Promise<T>): void;

declare const request: Promise<{value: string}>;

// normal correct call
call<MyAction>(request.then(({ value }) => ({ type: "foo", value })));

我遇到的问题是then()似乎允许很多返回值与T严格兼容。

以下是一些例子:

// bad: why no error on missing 'type'
call<MyAction>(request);

// good: error 'void' is not 'MyAction'
call<MyAction>(request.then(result => { }));

// good: error missing property 'type'
call<MyAction>(request.then(result => ({ fake: "foo" })));

// bad: why no error missing property 'value'
call<MyAction>(request.then(result => ({ type: "foo" })));

// bad: why no error for missing property 'type'
call<MyAction>(request.then(({ value }) => ({ value })));

// bad: why no error for unknown property 'fake'
call<MyAction>(request.then(({ value }) => ({ type: "foo", value, fake: "foo" })));

// bad: why no error for '{}' is not 'MyAction'
call<MyAction>(request.then(({ value }) => ({})));

我的问题是:

  1. 为什么这些承诺允许不兼容的T返回值? (缺少属性是主要问题。)
  2. 如果有的话,我可以做什么来使返回值更加严格地与传递给T的{​​{1}}相匹配?

1 个答案:

答案 0 :(得分:2)

  

// bad:为什么没有错误的未知属性'假'

由于TypeScript的结构类型允许更多信息,因此总是可以的。

这说明以下内容可以减少您的错误情况:

declare let both: Promise<{ type: string, value: string; }>;
declare let valueOnly: Promise<{ value: string }>;
declare let typeOnly: Promise<{ type: string }>;
declare let empty: Promise<{}>;

// Why no error?
both = valueOnly;
both = typeOnly;
both = empty;
  

为什么这些承诺允许不兼容的T返回值? (缺少属性是主要问题。)

因为类型T未在Promise中用作成员。

  

如果有的话,我可以做什么来使返回值更严格地匹配传递给

的T.

您可以将Promise界面更改为使用T

declare let both: Promise<{ type: string, value: string; }>;
declare let valueOnly: Promise<{ value: string }>;
declare let typeOnly: Promise<{ type: string }>;
declare let empty: Promise<{}>;

// Error!
both = valueOnly;
both = typeOnly;
both = empty;

interface Promise<T>{
  _ensureTypeSafety: T;
}

此处还添加了https://basarat.gitbooks.io/typescript/content/docs/tips/promise-safety.html