反应组件类型的变化和可分配性

时间:2019-03-18 18:34:44

标签: reactjs typescript

上下文

我有两个组成部分。一种成分的道具继承于另一种成分的道具。

   f_objs_save<-function(objects, dir1){
      for (obj in objects){
        print (obj)
        save(list=c(obj),file=paste0(dir1,"\\",obj,".Rdata"))
      }
    }

事实是:

  • declare namespace Props { interface Fruit { price: number; } interface Banana extends Fruit { curvature: number; } } declare const Fruit: React.FC<Props.Fruit>; declare const Banana: React.FC<Props.Banana>; 被React定义为道具的功能。
  • 我们知道函数类型在返回类型上是协变的,而在参数类型上是协变的。 Source

问题

现在,当尝试在TypeScript React.FC中将一个分配给另一个时,我们得到:

3.4.0-rc

问题

/** * ✅ Compile-time error. Function arguments are contravariant. */ const fruit: typeof Fruit = Banana; /** * ✅ No error. Function arguments are contravariant. */ const banana: typeof Banana = Fruit; /** * ✅ No errors as expected. */ const one: React.ReactComponentElement<typeof Fruit> = <Fruit price={3} />; /** * ⁉️ No errors (but expected one). Now it's covariant. */ const two: React.ReactComponentElement<typeof Fruit> = <Banana price={3} curvature={15} /> /** * ⁉️ No errors (but expected one). Now it's contravariant. */ const three: React.ReactComponentElement<typeof Banana> = <Fruit price={3} /> /** * ✅ No errors as expected. */ const four: React.ReactComponentElement<typeof Banana> = <Banana price={3} curvature={15} /> two为什么不引起错误?

2 个答案:

答案 0 :(得分:1)

避免使用JSX并使用React.createElement解决了此问题。

declare namespace Props {
  interface Fruit {
    price: number;
  }

  interface Banana extends Fruit {
    curvature: number;
  }
}

declare const Fruit: React.FC<Props.Fruit>;
declare const Banana: React.FC<Props.Banana>;

// ✅ 
const one: React.ReactComponentElement<typeof Fruit> = React.createElement(
  Fruit,
  { price: 1000 }
);

// ✅
const two: React.ReactComponentElement<typeof Banana> = React.createElement(
  Banana,
  { price: 1000, curvature: 12 }
);

/**
 * ✅ Compile-time error.
 * Type 'FunctionComponentElement<Banana>' is not assignable to type
 * 'ReactComponentElement<FunctionComponent<Fruit>, Pick<PropsWithChildren<Fruit>, "price" | "children">>'.
 * ...
 * fruits.tsx(10, 5): 'curvature' is declared here.
 */
const three: React.ReactComponentElement<typeof Fruit> = React.createElement(
  Banana
);

/**
 * ✅ Compile-time error.
 * Type 'FunctionComponentElement<Fruit>' is not assignable to type
 * 'ReactComponentElement<FunctionComponent<Banana>,
 * ...
 * Types of property 'propTypes' are incompatible. 
 */
const four: React.ReactComponentElement<typeof Banana> = React.createElement(
  Fruit,
  { price: 12 }
);

但是它会在VSCode中的道具上创建另一个we lose autocomplete

答案 1 :(得分:0)

不是答案,但这对于某些方法可能很有用。 (正在进行的工作,我不想迷失在import re result = re.sub(r'[^\x00-\x7f]',r'', text) 中)

git stash