TypeScript不会为不兼容的承诺返回错误

问题描述:

我正在研究一种通用API调用方法,该方法允许消费者传递请求回调,该回调应该返回一个承诺,该承诺会解析为指定的<T>有效内容(又名Action)。它归结为这样的事:TypeScript不会为不兼容的承诺返回错误

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传递给call<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<{}>; 

// 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

+0

不错!我没有意识到功能兼容性规则是如此不同。打开承诺'_ensureTypeSafety'工程!然而,现在它解开了一个更深层次的问题......'Promise '代表我希望返回的承诺,但在我的示例中'request'是类型'Promise '并且我想返回' T'在成功处理程序中...如果我启用'_ensureTypeSafety'类型'{值:字符串;类型'缺少'属性'类型'我原来的“正常正确调用”错误。 }'' - 我怎么表达这个?用'Promise'来表达这个可能吗? – Aaron

+0

看起来'promise'定义在TypeScript中每晚都被破坏:( – basarat

+0

它在TypeScript中修复了2017.03.08 – basarat