部分检查中的 Prop,但仍然未定义?

2024-04-11

我使用的是 Typescript 3.7.2,但在早期的 Typescript 版本中也会发生这种情况。 strictNullChecks 已打开。

我有这个小代码片段:

interface Test {
    one: boolean;
    two: boolean;
}

function getPropOrFalse(someTest: Partial<Test>, prop: keyof Test): boolean {
    if (prop in someTest) {
        const value = someTest[prop];
        return value; // <-- typescript determines this still to be boolean | undefined. Why??
    }
    return false;
}

我不明白,为什么我的常数value还是boolean|undefined在那之后prop in someTest查看。有人知道其背后的原理吗?

Edit:改变prop in someTest to someTest[prop] !== undefined顺便说一句,这不会改变结果。


这里发生了一些事情。第一的:

TypeScript 没有太多的余地区别 https://github.com/microsoft/TypeScript/issues/13195属性/函数参数之间missing以及那些现在但是undefined。 “可选性”注释foo?: Bar代表两种情况。和,Partial<Test>求值为具有两个可选属性的类型,相当于{one?: boolean, two?: boolean}.

因此我可以称之为:

getPropOrFalse({ one: undefined }, "one"); // oops

这就是编译器现在的方式(直到并且除非微软/TypeScript#13195 https://github.com/microsoft/TypeScript/issues/13195以某种方式得到解决)。我可以想象跳过很多圈子来制作呼叫签名getPropOrFalse()不允许someTest带有“present-but-”的参数undefined属性,但编译器可能仍然无法理解其实现中的含义getPropOrFalse(),所以你必须使用断言之类的。我想说,不与类型系统作斗争并允许存在但-更健康undefined特性。

The in运算符检查属性是否存在,但不检查属性的值是否为undefined或不。因此in运算符不足以检查可选属性,而typeof foo.prop === "undefined"实际上检查该属性是否是undefined或不。 (是的,我知道,但您的情况并非如此;请继续阅读!)这种差异可以通过以下方式证明:

function getOneOrFalse(someOne: { one?: boolean }): boolean {
    if ("one" in someOne) {
        return someOne.one; // error!  boolean | undefined        
    }
    if (typeof someOne.one !== "undefined") {
        return someOne.one; // okay
    }
    return false;
}

但是,显然,改变为typeof someTest[prop] === "undefined"不适合你的getPropOrFalse()功能:

function badGetPropOrFalse(someTest: Partial<Test>, prop: keyof Test): boolean {
    if (typeof someTest[prop] !== "undefined") {
        return someTest[prop]; // still error! boolean | undefined
    }
    return false;
}

是什么赋予了?这是第二件事:

问题与尝试输入防护有关indexed当属性不是单一属性时的属性访问(带括号)literal https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types。就你而言,自从prop是一个变量,并且是联合类型"one" | "two",编译器无法(或不愿意)执行控制流分析缩小(请参阅 microsoft/TypeScript#10530 https://github.com/microsoft/TypeScript/issues/10530)。我猜有一个attempt https://github.com/microsoft/TypeScript/pull/10565来解决这个问题,但它对性能产生了重大影响,因此它似乎已被放弃(或至少被推迟)。我预计性能会受到一些影响,因为为了使其工作,编译器必须特定跟踪“变量”的类型someTest当由变量索引时prop”,这不能轻易地转化为缩小类型someTest。 (毕竟,如果我有两个属性,prop1 and prop2两种类型keyof Test,我检查了someTest[prop1],它对类型没有影响someTest[prop2],尽管事实上prop1 and prop2根据类型系统,它们是相同的类型。)

处理这个问题的方法是减轻编译器跟踪变量索引的负担,并将其分配给新的变量const首先是变量,正如另一个答案中提到的:

function getPropOrFalse(someTest: Partial<Test>, prop: keyof Test): boolean {
    const val = someTest[prop]; // boolean | undefined
    if (typeof val !== "undefined") {
        return val; // okay
    }
    return false;
}

当然,一旦我们开始像这样重构,我们就可以一路走下去:

function simplestGetPropOrFalse(someTest: Partial<Test>, prop: keyof Test): boolean {
    return someTest[prop] ?? false;
}

(它使用新添加的无效合并 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing操作员)


好的,希望这有助于解释发生了什么。祝你好运!

链接到代码 https://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgCoQM5mQbwFDKHID2IEAXMgEbHEA2EcIA3AUWAO7GU32Mt4AvnjwBzCGAAKUYgAcA8lABicOhggAKHCTKUAriAAmEGKAiHkggDTIARKQi2AlKzwwDCMMFLU4hgOIS0nKKKmqaGMQAthDoWJSScFBeqgA8cWAAfDayMrKUANYQAJ7EMGiYYE48tAxMuGyEwOUauXLIoMiRMRlODUQDyFASelAgXdGxlQDabbIAuszIAPTLyNAyUACE1LX8yAA+yAbGpmSGjZaXzcgaYMWyEGUTPTNz88hbALxfdicmZkMzn6g0IwzAo3G3SmWFmeUWKzWWGAdDo6ygmx2vDq4yO-zO5kuwgG4MhyHg4VYwjcHi8PnEYHkZFCqnUGmhTIouB0EAA-DU+PVBNVdoLxvgBjcNPYyLYOlDJpy+hLQUMRmMXhBOQA6BxLVbozGEbH7PFGAHnVXIInXFr3R7PDlkXVkT4-P7mglA5WXEnqhUxHV6xEkApwYo2v0QjUU9RUkQ0kCebzjBnBBTKVkRSYZBJJFJ0dKVbLIOaFErPXoCnEgwgIUhYZAAN1UyF+0IycLkCINJvqZtOgNtt3tT3KLbR31+tnxgOBKtBpI1E-1a2IYYjA2JRCX41jEHjieTPgwwCisgYWECUjyLPC7JzlTzyWAaQyJbLyCKpXKVdFNYXNVowDGEwC7BZkF5XlySzQ8gA

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

部分检查中的 Prop,但仍然未定义? 的相关文章

随机推荐

  • 如何将复杂的 HTML 表单发布为 JSON?

    我的网页中有一个非常复杂的表单 用户实际上构建了一个复杂的对象 UI 使用 jQuery 进行处理 显示 隐藏部分 复制和删除子表单 尽管可能 但简单地在用户提交时发布表单似乎并不是最好的解决方案 为字段 可以有对象数组 创建唯一的名称并在
  • 将 UINavigationController 添加到现有的 UIViewController

    如何将现有的 UIViewController 使用presentModalViewController 呈现 添加到 UINavigationController 当用户点击按钮时 需要推送我的详细视图的新副本 换句话说 pushView
  • 计算数组属性的内存语义?

    这是一个允许用户标记事物的应用程序 标签只是字符串 一个数组TagHolder对象保存应用程序中使用的所有标签的列表 并用一个布尔值告诉是否选择了该标签 但这是一个实现细节 外部接口调用两个方法 selectedTags and setSe
  • 将属性和值从第 4 个父节点填充到 XML 文件的所有父节点

    我是 XSLT 新手 希望将相同的属性和值添加到从第二个父节点开始的所有父节点 这里的逻辑应该是 如果存在主节点 则属性 Mainattribute 应该是一次 并且对于主节点下的所有父节点的其余部分应该具有不同的属性 childattri
  • 创建二进制 PBM/PGM/PPM

    我试图了解如何创建二进制 PBM PGM PPM 文件 据我所知 每种格式有两种类型 普通格式和原始格式 例如 黑色 PBM 5x5 的结构如下所示 P1 This is a comment 5 5 1 1 1 1 1 1 1 1 1 1
  • Visual Studio 2015 如何禁用异常输出

    我正在制作一个带有更新和绘制的 C 应用程序 我发现更新确实很慢 尽管没有任何沉重的表达 在独立于 Visual Studio 启动我的应用程序后 我发现它的速度快了 100 倍 问题是 对于每个 try catch VStudio 都会在
  • 使用 asp:Button 将参数传递到函数中

    我正在尝试将参数传递给函数onClick of an asp Button
  • 从 Ada 代码构建静态库,无需 GNAT 即可链接

    我正在尝试从 Ada 代码创建一个静态库 该库可以与一些 C 代码链接 而无需使用 GNAT 工具进行最终链接 我的用例是 我正在尝试将一个用 Ada 编写的库交付给一个为嵌入式目标构建的 C 代码库 为目标构建最终二进制文件的工具链不包含
  • 从使用 List 的 .Net 调用 Java Web 服务

    我正在开发一个将由 Net 客户端使用的 Java Web 服务 该服务公开一个接受对象作为参数的方法 该对象有一个 List 类型的字段 Row 类也有一个 List 类型的字段 现在 当 Java 客户端使用此服务时 它会正确地将类型视
  • 是否可以在 React 中使用 Polymer?

    我一直在使用 React 并希望在 React 中使用 Polymer 标签 React 无法识别 Polymer 标签 因为 React 仅处理基本 DOM 标签 有没有办法将 Polymer 标签添加到 React DOM 库 对的 这
  • 有独立的Python类型转换库吗?

    是否有独立的类型转换库 我有一个仅理解字节 字符串的数据存储系统 但我可以标记元数据 例如要转换为的类型 我可以破解一些简单的类型转换器系统 就像我之前的所有其他应用程序所做的那样 或者我可以希望使用一个独立的库 除非我找不到一个 对于这样
  • 将 C# Stateful Service Fabric 应用程序从 Visual Studio 部署到 Linux

    编辑 04 06 18 gt 更新了问题的最新状态 因此 我有一个正在运行的 Net 4 6 Stateful Service 它当前在部署在 Azure 上的 Windows Service Fabric 集群上运行 从 09 2017
  • R(以前称为 Excel Solver)中预算分配的优化

    我将 Excel 中遇到的问题翻译成 R 我想以 Gesamt 由函数返回 最大化的形式分配固定预算 NrwGes lt function Budget Speed maxnrw cpcrp BudgetA lt Budget 1 Budg
  • 合并具有索引的数据帧,其中一个数据帧包含另一个数据帧(但不相同)

    例如 df1 具有形状 533 2176 指数如Elkford 5901003 DM 01010 df2 具有形状 743 12 指数如5901003 df1 索引括号中的数字将与 df2 的索引匹配 正如形状所示 一些索引根本不匹配 现在
  • Jquery修改每个循环中的元素

    使用jquery 我想循环具有 item 类的所有元素 并根据元素的索引应用不同的背景颜色 mapcolor 是颜色数组 长度 具有 item 类的元素数量 each item function i e e css background c
  • C# - 互斥锁的锁定问题

    我有一个 Web 应用程序 可以控制哪些 Web 应用程序从我们的负载均衡器获取服务流量 Web 应用程序在每个单独的服务器上运行 它在 ASP NET 应用程序状态的对象中跟踪每个应用程序的 输入或输出 状态 并且只要状态发生更改 该对象
  • WPF ControlTrigger IsMouseOver

    当我尝试更改 WPF 触发器 IsMouseOver 按钮的图像时 控件闪烁很多 此问题有任何解决方法吗 使用相对绑定并找到更深层的祖先 它必须具有永久的IsMouseOver财产
  • Javascript - 你能在错误中抛出一个对象吗?

    是否可以使用抛出一个对象Error 在下面的示例中 控制台显示undefined try throw Error foo bar catch err console log err message foo 您可以抛出自己的对象 并将 Err
  • 模板内的 MVC 助手

    我正在尝试在模板中使用 kendo MVC 助手 远程模板文件加载如下 http docs kendoui c om howto load templates external files remote templates http doc
  • 部分检查中的 Prop,但仍然未定义?

    我使用的是 Typescript 3 7 2 但在早期的 Typescript 版本中也会发生这种情况 strictNullChecks 已打开 我有这个小代码片段 interface Test one boolean two boolea