Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我怎样才能做出反应;如果;组件的行为就像一个真实的;如果;打字稿?_Javascript_Reactjs_Typescript - Fatal编程技术网

Javascript 我怎样才能做出反应;如果;组件的行为就像一个真实的;如果;打字稿?

Javascript 我怎样才能做出反应;如果;组件的行为就像一个真实的;如果;打字稿?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我使用React制作了一个简单的功能组件: import React, { ReactElement } from "react"; interface Props { condition: boolean; comment?: any; } export function If(props: React.PropsWithChildren<Props>): ReactElement | null { if (props.condition) {

我使用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;
}

现在我有了另一个组件,它呈现以下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>
);
const-animal:animal | undefined=。。。;
返回(
//这似乎不可能。
原因:如果我们从更改组件的内容

if (props.condition) {
  ...
}
相反

if (!props.condition) {
  ...
}
您将发现,这次您希望以相反的方式处理类型diff

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

interface AnimalProps{
//以前
动物:动物;
//之后
动物:不可为空;
}
它不是由
If
组件的条件生成的,但由于您仅在该条件内使用
子组件
,因此在以下条件下将
子组件的道具设计为
不可为空
,是有意义的

类型
动物
不包含
未定义


通过使用渲染回调,我能够键入返回参数不可为null

我无法修改您的原始
If
组件,因为我不知道您的
条件
断言了什么,也不知道它断言了什么变量,即
条件={animal!==未定义的| | true}

因此,不幸的是,我定义了一个新组件
来处理这种情况:

interface IsDefinedProps<T> {
  check: T;
  children: (defined: NonNullable<T>) => JSX.Element;
}

function nonNullable<T>(value: T): value is NonNullable<T> {
  return value !== undefined || value !== null;
}

function IsDefined({ children, check }: IsDefinedProps<T>) {
  return nonNullable(check) ? children(check) : null;
}
我这里有一个工作示例

简短回答

你不能

由于您已将
animal
定义为
animal | undefined
,因此删除
undefined
的唯一方法是创建一个防护或将
animal
重新编码为其他内容。您已在条件属性中隐藏类型防护,TypeScript无法知道那里发生了什么,因此它无法知道您是c在
动物
未定义
之间选择。您需要将其施放或使用

考虑一下:这可能会让人感觉更干净,但它创建了一段需要理解和维护的代码,可能是由更底层的其他人来理解和维护的。本质上,您正在创建一种由React组件组成的新语言,除了TypeScript之外,还有人需要学习它

有条件地输出JSX的另一种方法是在
render
中定义包含条件内容的变量,例如

render() {
  const conditionalComponent = condition ? <Component/> : null;

  return (
    <Zoo>
      { conditionalComponent }
    </Zoo>
  );
}
render(){
const conditionalComponent=条件?:空;
返回(
{conditionalComponent}
);
}

这是其他开发人员可以立即识别的标准方法,不必查找。

不确定是否可以在typescript中告诉他您已经检查了空安全性。可能
{animal!==未定义&&}
它能用吗?
@OlivierBoissé我不能用它syntax@paul是的,但它不是类似于put吗最后呢?我也在同一条船上,这让我很难过,这似乎不可能。也许发布一个TypeScript功能请求会导致类型检查器的更新?我不确定它是如何解决我的问题的。动物组件与If组件没有任何关系。它不应该自我调整以匹配If组件。另外,我也不确定它是如何非空的艾布尔和我的工作有什么关系吗problem@EliyaCohen更新,此答案需要附加任何内容吗?我已对您的答案进行了投票,但我无法接受,因为这不是一个解决方案。可能会在将来解决,因为TS和React将使这一问题成为可能。这是一个不错的方法,但不幸的是,它无法实现全部目的使用
If
组件(使其看起来干净)
type T34 = NonNullable<string | number | undefined>;  // string | number
interface AnimalProps {
  // Before
  animal: Animal;
  // After
  animal: NonNullable<Animal>;
}
interface IsDefinedProps<T> {
  check: T;
  children: (defined: NonNullable<T>) => JSX.Element;
}

function nonNullable<T>(value: T): value is NonNullable<T> {
  return value !== undefined || value !== null;
}

function IsDefined({ children, check }: IsDefinedProps<T>) {
  return nonNullable(check) ? children(check) : null;
}
  const aDefined: string | undefined = mapping.a;
  const bUndefined: string | undefined = mapping.b;

  return (
    <div className="App">
      <IsDefined check={aDefined}>
        {aDefined => <DoSomething message={aDefined} />} // is defined and renders
      </IsDefined>
      <IsDefined check={bUndefined}>
        {bUndefined => <DoSomething message={bUndefined} />} // is undefined and doesn't render
      </IsDefined>
    </div>
  );
render() {
  const conditionalComponent = condition ? <Component/> : null;

  return (
    <Zoo>
      { conditionalComponent }
    </Zoo>
  );
}