Javascript 我怎样才能做出反应;如果;组件的行为就像一个真实的;如果;打字稿?
我使用React制作了一个简单的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) {
功能组件:
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>
);
}