草庐IT

javascript - 流: check type of thenable

coder 2025-04-01 原文

我有一个函数接受 thenable(具有 then() 方法的对象;参见 MDN JavaScript docs: Promise.resolve() 的顶部)或其他:

function resolve<T>(value: {then: ()=>T}|T) {
    if (value && value.then) {
        console.log('thenable', value.then);
    } else {
        console.log('not thenable');
    }
}

Try Flow demo

当我在此 if 语句中访问 value.then 时,Flow 会报错。我可以用 (value: any).then 修复它,但这看起来很老套。

谁能推荐一种类型检查的好方法?

最佳答案

好问题!这是 Flow 团队在过去几周一直在努力解决的问题!

问题是什么

if (value && value.then) {
  // What is the type of `value` here?
} else

在 if 语句中,value 的类型是什么?如果 Tstring,那么它将是 {then: ()=>T},如您所料。但是如果 T{ then: string } 呢?据我们所知,T 可能有一个名为 then 的属性!

Flow 团队正在做什么来解决这个问题?

  • 添加确切的对象类型。这个问题来自不知道工会的一个分支是否可能拥有属性(property)。使用确切的类型,您可以准确地告诉 Flow 一个对象具有哪些属性。
  • 允许value.then属性检查,并将value.then的类型细化为mixed

其中很多工作已经在 master 中了。您可以查看 flowtype.org/try,它目前由 master 运行。 Your example on flowtype.org/try

一旦这些东西落地(一些出现在 v0.31.0 中,一些出现在 v0.32.0 中),我们将对其进行记录和博客。

编辑:添加更多信息

3个主要问题

我们正在努力解决 3 个一般性问题。

  • 我们什么时候应该在条件语句中允许value.then?如果我们只允许 value.then 当我们确定 value 有一个 then 属性时,那么我们可以捕获像 value 这样的拼写错误.tehn。但是,惯用的 JavaScript 经常测试对象中可能存在或不存在的属性。
  • 如果条件为真或假, 的类型是什么。在提供的示例中,value 是联合类型。看起来 value && value.then 的目的是检测函数是否正在使用联合的左分支。然而,Flow 不能安全地选择一个分支,因为 T 可能有一个 then 字段。
  • 如果条件为真或假,value.then 的类型是什么。同样,T 可能是一个像 { then: string } 这样的对象,所以 value.then 可能是任何东西

我们的解决方案

When should we allow value.then in a conditional

我们将始终允许 value.then。这意味着我们不能轻易捕获属性名称拼写错误,但这意味着我们可以支持更多地道的 JavaScript。 Flow 的主要原则之一是它可以很好地与人们倾向于编写的 JavaScript 配合使用。

What is the type of value if the conditional is true or false.

如果 Flow 确定联合类型中只有一个分支可以工作,它会将 value 的类型细化到该分支。否则,value 将不会被细化。精确类型将对此有所帮助

What is the type of value.then if the conditional is true or false

如果 Flow 确定只有联合类型的一个分支可以工作,它会将 value.then 的类型细化为 then 属性的类型那个分支。如果 Flow 确定没有分支具有该属性,它就会出错。否则,它将使用 mixed 类型。精确类型也有助于此。

什么是精确类型

{ x: string } 是具有 x 属性的对象类型,其类型为 string

var example1: { x: string } = { x: 'hello' }; // This is ok
var example2: { x: string } = { x: 'hello', y: 123 }; // This is also ok

这对于惯用的 JavaScript 很有用,但让 Flow 很难说一个对象类型没有属性。所以我们要添加精确类型。

{| x: string |} 是具有属性 x 的对象类型,其类型为 string 但没有其他属性。

var example1: {| x: string |} = { x: 'hello' }; // This is ok
var example2: {| x: string |} = { x: 'hello', y: 123 }; // Error! Extra property y!

这很有帮助,因为你可以这样写:

type Foo = {| x: string |} | {| y: string |};

function test(arg: Foo): string | void {
  if (arg.x) {
    return arg.x;
  }
}

一旦我们推出这些,我们将记录它们!所以请擦亮眼睛!

关于javascript - 流: check type of thenable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39018508/

有关javascript - 流: check type of thenable的更多相关文章

  1. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  2. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  3. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  4. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

  5. ruby - 使用 Selenium WebDriver 启用/禁用 javascript - 2

    出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=

  6. ruby - Watir-Webdriver 是否支持点击目标为 javascript 的链接? - 2

    我是Ruby和Watir-Webdriver的新手。我有一套用VBScript编写的站点自动化程序,我想将其转换为Ruby/Watir,因为我现在必须支持Firefox。我发现我真的很喜欢Ruby,而且我正在研究Watir,但我已经花了一周时间试图让Webdriver显示我的登录屏幕。该站点以带有“我同意”区域的“警告屏幕”开头。用户点击我同意并显示登录屏幕。我需要单击该区域以显示登录屏幕(这是同一页面,实际上是一个表单,只是隐藏了)。我整天都在用VBScript这样做:objExplorer.Document.GetElementsByTagName("area")(0).click

  7. 网页设计期末作业,基于HTML+CSS+JavaScript超酷超炫的汽车类企业网站(6页) - 2

    🎉精彩专栏推荐💭文末获取联系✍️作者简介:一个热爱把逻辑思维转变为代码的技术博主💂作者主页:【主页——🚀获取更多优质源码】🎓web前端期末大作业:【📚毕设项目精品实战案例(1000套)】🧡程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作(110套)】🌎超炫酷的Echarts大屏可视化源码:【🔰Echarts大屏展示大数据平台可视化(150套)】🔖HTML+CSS+JS实例代码:【🗂️5000套HTML+CSS+JS实例代码(炫酷代码)继续更新中…】🎁免费且实用的WEB前端学习指南:【📂web前端零基础到高级学习视频教程120G干货分享】🥇关于作者:💬历任研发工程师,技术组长,教学总监;

  8. ruby-on-rails - 在页面的最底部包含 javascript 文件 - 2

    我有一个Rails应用程序。还有一个javascript(javascript1.js)文件必须包含在每个View的最底部。我把它放在/assets/javascripts文件夹中。Application.js包含以下代码//=requirejquery//=requirejquery_ujs//=someotherfiles//=require_directory.即使Application.js中不包含javascript1.js,它也会自动包含,不是吗?那么我怎样才能做我想做的事呢? 最佳答案 单独定义、包含和执行您的java

  9. ruby-on-rails - 为 rails 中的 javascript 生成完整的 url(类似于 javascript_path,但是是 url) - 2

    如何生成指向javascript文件的绝对链接。我想应该有类似下面的东西(不幸的是它似乎不可用):javascript_url'main'#->'http://localhost:3000/javascripts/main.js'代替:javascript_path'main'#->'/javascripts/main.js'我需要绝对URL,因为该javascript文件将用于书签。另外我需要相同的css文件。谢谢,德米特里。 最佳答案 javascript和css文件的绝对URL现在在Rails4中可用ActionView::H

  10. ruby - 处理在 keyup 事件上发生的 javascript 弹出窗口 - 2

    我在HTML页面上有一个文本字段,用于检查您是否输入了1到365之间的值。如果用户输入了无效值,如非数字字符或不在范围内的值,它显示一个弹出窗口。我在watirwiki上看到有一个select_no_wait方法,用于在您从列表中选择无效值时关闭弹出窗口。处理键盘事件时出现的弹出窗口的好方法是什么?我是否需要按照select_no_wait方法的实现方式进行操作,或者我们是否可以启动一个不同的进程来消除调用set方法时可能出现的弹出窗口。带有Javascript验证函数的HTML文件示例如下:varnum=0functionvalidate(e){varcharPressed=Stri

随机推荐