【问题标题】:Using higher order component in Typescript在 Typescript 中使用高阶组件
【发布时间】:2018-05-23 14:28:45
【问题描述】:

我正在尝试将 react-i18next 与 Typescript 一起使用,但遇到了一些问题。

这是我期待的道具界面。

import * as i18n from 'i18next';

export interface ReactI18nProps {
  t: i18n.TFunction;
}

然后我有一个导航组件,我编写它。

import { translate } from 'react-i18next';

function Navigation({ t }: ReactI18nProps) {
  const userProfile = JSON.parse(localStorage.getItem('profile') || '');
  return (
    ...
  );
}

export default translate('navigation')(Navigation);

现在我只想渲染这个我编写的组件

function Appliances({ location }: NavLinkProps) {
  const userId = location && location.state.userId;
  return (
    <div>
      <Navigation />
    </div>
  );
}

但是,此时,TS 失败了,我收到以下错误

Type '{}' is not assignable to type 'IntrinsicAttributes & ReactI18nProps'.
  Type '{}' is not assignable to type 'ReactI18nProps'.
    Property 't' is missing in type '{}'.

谁能解释我做错了什么。

【问题讨论】:

    标签: reactjs typescript i18next higher-order-components react-i18next


    【解决方案1】:

    如错误消息所示:

    类型“{}”中缺少属性“t”

    您的组件期望道具是:

    interface ReactI18nProps {
        t: i18n.TFunction;
    }
    

    但是你没有通过这个t:

    <Navigation />
    

    您可以将此 t 属性设为可选:

    interface ReactI18nProps {
        t?: i18n.TFunction;
    }
    

    或者满足它:

    <Navigation t={ (key: string, options: i18n.TOptions) => return getTranslation(key, options) } />
    

    编辑

    基于react-i18next translation function 的类型定义:

    function translate<TKey extends string = string>
        (namespaces?: TKey[] | TKey, options?: TOptions)
            : <C extends Function>(WrappedComponent: C) => C;
    

    您传递的组件类型与您返回的确切类型相同,这意味着使用了相同的道具类型。
    在这种情况下,您需要使用可选的t,因为有时它在没有此属性的情况下使用(当您调用它时),但随后它与t 一起使用(当translate 方法调用它时)。

    为避免编译器抱怨t 可能未定义,您可以使用non-null assertion operator:

    function Navigation({ t }: ReactI18nProps) {
        ...
        const translation = t!(...);
        ...
    }
    

    请注意,它使用的是t! 而不仅仅是t。

    【讨论】:

    • 我不想传递 t 因为它来自组合组件,并且如果我将属性类型声明为可选 typescript 会抱怨该对象可能未定义(在这种情况下我将不得不验证它是否已定义)。有没有更好的解决方案?
    • 我不确定您要做什么。如果您需要 t 则传递它,如果您不需要它则将其从道具和/或 Navigation 参数中删除。
    • 据我了解,t 来自 HOC translate,所以我不必明确传递它。
    • 检查我修改后的答案
    • 谢谢,非空断言运算符正是我想要的! :)
    猜你喜欢
    • 2020-02-06
    • 2017-09-26
    • 1970-01-01
    • 2019-07-25
    • 2020-08-31
    • 2018-09-17
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    相关资源
    最近更新 更多