不使用 As 的条件类型

2023-11-30

我有一个名为movies可以采用定义为以下接口的两种形状的形式:

interface BaseMovie {
  id: number;
  title: string;
}

interface MultiSearchResult extends BaseMovie {
  media_type: "movie" | "tv" | "person";
}

我知道当另一个变量时,triggeredSearch为真,形状将是MultiSearchResult。形状将是BaseMovie when triggeredSearch是假的。

使用它来渲染每个项目时

<ul>
  {movies.map((movie, i) => (
    <li key={i}>{!triggeredSearch ? movie.title : movie.media_type}</li>
  ))}
</ul>

我收到以下警告:

属性“media_type”在类型“BaseMovie | ”上不存在多重搜索结果'。 类型“BaseMovie”上不存在属性“media_type”。ts(2339)

有没有办法,除了使用as关键字(即(movie as MultiSearchResult).media_type),声明一个movie is a MultiSearchResult when triggeredSearch是真的?

可以找到完整的示例here.


TypeScript 无法根据另一个变量的值缩小一个变量的类型,但它can根据工会成员之一缩小工会类型。所以如果你可以把triggeredSearch and movies在相同的数据结构中,您可以使用可区分联合来区分事物:

type Example =
  { triggeredSearch: true, movies: null | MultiSearchResult[] }
  |
  { triggeredSearch: false, movies: null | BaseMovie[] };

declare const data: Example;

// Side note: Using thea rray index as the key an anti-pattern if the
// arrays contents ever change, more here:
// https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318
const items = data.triggeredSearch
  ? data.movies?.map((movie, i) => <li key={i}>{movie.media_type}</li>)
  : data.movies?.map((movie, i) => <li key={i}>{movie.title}</li>);

const result = <ul>{items}</ul>;

游乐场链接

如果不能,您可以使用类型断言函数而不是as,如果断言为 false,它的优点是会给出运行时错误:

function assertMultiSearchResult(movie: BaseMovie): asserts movie is MultiSearchResult {
    if (!("media_type" in movie)) {
        throw new Error(`Given 'movie' is not a 'MultiSearchResult');
    }
}

Then:

<ul>
    {movies?.map((movie, i) => {
        let content: string;
        if (triggeredSerach) {
            assertMultiSearchResult(movie);
            content = movie.media_type;
        } else {
            content = movie.title;
        }
        return <li key={i}>{content}</li>;
    })}
</ul>

更冗长,但也更安全。

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

不使用 As 的条件类型 的相关文章

随机推荐

  • 如何在Mongo中“(WHERE)列=列”?

    我喜欢 Mongo 做简单的事情 所以我希望用它来做更高级的事情 在我需要这个之前 这一切都很好 UPDATE tbl SET a b WHERE c lt gt 0 The a b部分是我无法弄清楚的 我尝试了 mongodb org 但
  • Join表的最后一条记录

    我正在寻找正确的 SQL 代码来连接 2 个表并仅显示详细信息表的最后一条记录 我有一个有 2 个表的数据库 Deals DealID Dealname DealDetails DealComments dcID DealID Commen
  • 突出显示输入字段中的文本

    我正在尝试在 JS 中创建一个脚本 突出显示用户输入的某些文本 有点像来自的 测试字符串 框 https regex101 com 但似乎无法在使用时更改输入字段本身内的文本 有谁知道我该怎么做 无法设置内容的样式input字段 或text
  • 我怎样才能将双标参数折叠成空?

    在方法调用中对空数组进行 Splat 扩展 可以有效地将参数减少为空 为了清楚起见 添加了空括号 def foo end def bar args foo args end bar 1 ArgumentError as expected b
  • C++ 中的动态对象?

    我意识到我很可能会得到很多 你不应该这样做 因为 的答案 他们是最受欢迎的 我可能会完全同意你的推理 但我很好奇这是否是可能的 正如我所设想的那样 是否可以在 C 中定义一种动态 通用对象类型 在其中我可以动态创建在系统的键 值类型中存储和
  • 如何判断屏保正在运行?

    人们可能建议的一种解决方案是定期查找特殊的 屏幕保护程序 桌面 如果存在 则将其视为正在运行的屏幕保护程序 但显然并非所有屏幕保护程序都是如此 因为某些提到的桌面始终存在 有没有更可靠的解决方案 请参阅带有 SPI GETSCREENSAV
  • 在开玩笑的测试中,shallow 抛出意外的 token < 错误

    我目前正在使用以下堆栈设置单元测试 React v15 组件是用 typescript tsx 编写的 测试设置是使用 jest v21 和酶 v3 完成的 测试文件被编写为普通的 js 文件 不幸的是 酶似乎出了问题 因为我不断收到错误
  • 淘汰赛绑定不会使用简单可观察值数组进行更新

    我的视图模型中有一个字符串列表 要编辑它们 我希望每个都显示为 li 带有一个文本框和一个 li
  • python pandas 3个最小值和3个最大值

    如何在 pandas 数据框中的列中找到 3 个最小值和 3 个最大值的索引 我找到了找到最大值和最小值的方法 但没有找到找到 3 的方法 你尝试了什么 你可以排序s sort 然后打电话s head 3 index and s tail
  • 如何存储配置文件并使用 React 读取它

    我是 React js 的新手 我已经实现了一个组件 在该组件中我从服务器获取数据并使用它 如下所示 CallEnterprise function TenantId fetchData http xxx xxx xx xx 8090 En
  • 使用控制器之间的共享服务进行脏检查,一种方法有效,另一种则无效?

    在尝试回答有关在两个单独的控制器之间共享数据的问题时 我遇到了一个问题 我通常使用服务来完成此任务并开始创建 jsfiddle 但我无法让它工作 经过一番调试后 如果我在中动态创建属性setActivePersonWorks person
  • Android,快速有效地查找目录大小的方法?

    在我的应用程序中 我想找到许多目录的大小 并且需要它快速运行 我见过这些方法 其中两个不够快 第三个仅适用于Java 不适用于Android First public static long folderSize File director
  • codeigniter 301 使用旧 url 的路由器进行重定向,并且不保留重定向

    我有一个 codeigniter 网站 我正在为其做 SEO 所以问题是大多数 url 都缓存在搜索引擎中 我的旧 url 是 product details productname productid 我的新网址将是 tours city
  • 无法解析:com.google.firebase:firebase-auth:9.0.0 [重复]

    这个问题在这里已经有答案了 As per Firebase Android 代码实验室教程 同时添加com google firebase firebase auth 9 0 0在 build gradle 依赖项中 出现以下错误 错误 2
  • JS 对象字面量中的“类似方法”语法是什么[重复]

    这个问题在这里已经有答案了 使用ES6类糖 我们可以这样定义函数 class Foo constructor props myFn 在 JS 对象字面量中 我们可以定义getters and setters像这样 foo get data
  • 在 App.xaml 上添加 BasedOn 样式会在 App() { InitializeComponent(); 上崩溃}

    使项目适应模板10 我进入 App xaml 中的继承样式崩溃了 看起来像模板10 不支持继承或扩展样式 我试图延长字幕样式 from 标题样式但我收到 COM 异常获取Xaml类型 in XamlTypeInfo g cs 我的应用程序
  • TeamCity - Microsoft.Bcl.Build 依赖项

    我刚刚突然向我的存储库提交了一些代码更改 在几周的良好状态之后 TC 构建开始失败 因为无法下载 Microsoft Bcl Build 1 0 6 的 NuGet 包 我最终不得不手动将包目录的内容复制到 TC 构建位置 这完全违背了 N
  • “Prism-ES2 错误:GL_VERSION (major.minor) = 1.4”的原因可能是什么?

    我正在尝试使用 eclipse IDE 在 Oracle Linux 中开发简单的 javafx 程序 我已经安装了 jdk 7 并且所有程序都运行正常 除了它显示 Prism ES2 Error GL VERSION major mino
  • Unity无法设置ActiveScene

    我正在切换场景 SceneManager LoadScene Scene2 Debug Log Current scene SceneManager GetActiveScene name 调试说 Current scene Scene1
  • 不使用 As 的条件类型

    我有一个名为movies可以采用定义为以下接口的两种形状的形式 interface BaseMovie id number title string interface MultiSearchResult extends BaseMovie