reactjs 子组件中未定义变量的类型AssertReact TypeScript

wn9m85ua  于 2023-04-11  发布在  React
关注(0)|答案(2)|浏览(128)

我有以下代码:

<Show when={!!icon} fallback={<SVG src={defaultIcon}/>}>
     <SVG src={icon!} className={styles.buttonIcon} />
</Show>

因为icon可以是未定义的,所以我创建了一个 Package 器来 Package SVG组件,但是typescript仍然认为icon可以是未定义的,即使它出现的唯一方式是定义了icon。有没有一种方法可以告诉typescript,当icon在Show Package 器中使用时,它将被定义?
我知道

<SVG src={icon ?? defaultIcon} className={styles.buttonIcon} />

对于这种情况“更好”,但在一些更复杂的情况下,我希望使用这个定制的Show Package 器

bqjvbblv

bqjvbblv1#

你可以试试

{ icon && <SVG src={icon} className={styles.buttonIcon} /> }

或者

{ icon ? <SVG src={icon} className={styles.buttonIcon} /> : <SVG src={defaultIcon}/>  }
gv8xihay

gv8xihay2#

就像你提到的,在简单的情况下,你可以依靠TypeScript的隐式类型收缩,但在更复杂的情况下,当你提取条件时,你会失去隐式类型收缩。解决方案是显式地缩小类型。这里是一个快速草稿,你的条件组件的类型安全版本可能是什么样子:

const When = <P extends Record<string, unknown>, T extends P>({
  props,
  predicate,
  component: Component,
  fallback: Fallback,
}: {
  props: P;
  predicate: (props: P) => props is T;
  component: React.ComponentType<T>;
  fallback: React.ComponentType<P>;
}) => (predicate(props) ? <Component {...props} /> : <Fallback {...props} />);

用法有点冗长,但您可以将每个prop值提取到自己的函数中:

<When
  props={{ src: icon, className: styles.buttonIcon }}
  predicate={<T extends { src: string | null | undefined }>(
    props: T
  ): props is T & { src: string } => props.src != null}
  component={SVG}
  fallback={() => <SVG src={defaultIcon} />}
/>

相关问题