javascript - 如何制作一个像 Typescript 中真正的 "If"一样工作的 React "if"组件?

标签 javascript reactjs typescript

我做了一个简单的<If />使用 React 的功能组件:

import React, { ReactElement } from "react";

interface Props {
    condition: boolean;
    comment?: any;
}

export function If(props: React.PropsWithChildren<Props>): ReactElement | null {
    if (props.condition) {
        return <>{props.children}</>;
    }

    return null;
}

它让我可以编写更清晰的代码,例如:

render() {

    ...
    <If condition={truthy}>
       presnet if truthy
    </If>
    ...

在大多数情况下,它工作得很好,但是当我想检查例如给定变量是否未定义然后将其作为属性传递时,它就成为一个问题。我举个例子:

假设我有一个名为 <Animal /> 的组件它具有以下 Props:

interface AnimalProps {
  animal: Animal;
}

现在我有另一个组件可以呈现以下 DOM:

const animal: Animal | undefined = ...;

return (
  <If condition={animal !== undefined} comment="if animal is defined, then present it">
    <Animal animal={animal} /> // <-- Error! expected Animal, but got Animal | undefined
  </If>
);

正如我所评论的,虽然事实上动物没有定义,但我无法告诉 Typescript 我已经检查过它。 animal! 的断言会起作用,但这不是我想要的。

有什么想法吗?

最佳答案

这似乎不可能。

原因:如果我们将 If 组件的内容更改为

if (props.condition) {
  ...
}

相反

if (!props.condition) {
  ...
}

您会发现,这次您希望以相反的方式处理类型差异。

  <If condition={animal === undefined} comment="if animal is defined, then present it">
    <Animal animal={animal} /> // <-- Error! expected Animal, but got Animal | undefined
  </If>

这意味着它不是独立的,从而得出这样的结论:在这种情况下,在不触及两个组件中的任何一个的情况下不可能进行此类类型差异。

<小时/>

我不确定最好的方法是什么,但这是我的想法之一。

您可以使用 typescript 的
定义Animal组件的 Prop animal Distributive conditional types :不可空

文档

type T34 = NonNullable<string | number | undefined>;  // string | number

使用

interface AnimalProps {
  // Before
  animal: Animal;
  // After
  animal: NonNullable<Animal>;
}

它不是由 If 组件的条件生成的,但由于您只在该条件内使用子组件,因此设计 子组件是有意义的 的 props 为 none nullable,条件是

type Animal do contain undefined.

关于javascript - 如何制作一个像 Typescript 中真正的 "If"一样工作的 React "if"组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60393467/

相关文章:

javascript - React 组件 - Plotly 图表创建器

node.js - Mongoose - 多个数据库连接

javascript - 为ajax内容添加淡入淡出效果

html - 如何将缓冲区时间范围数据从 HTML5 视频播放器引用映射到进度条?

javascript - 自定义弹出窗口

reactjs - React Router Redirect 在专用路由中不起作用

javascript - 模板中的 Angular 2 主题标签是什么意思?

javascript - Angular4 http 获取解析错误

以 PHP-Variable 作为传递参数的 JavaScript 调用函数

javascript - Fabric.js 相对于 getZoom() 和 getWidth()/getHeight() 定位元素