我有一个HOC,它为包装的组件提供一个属性。
我想写的打字稿类型定义,正确地公开由这个HOC创建的组件的道具类型:基本上复制(推断)包装组件的道具类型,并删除我的HOC提供的属性。有可能吗?
在下面的示例中,我有一个HOCwith Bar
,它为任何接受它的包装组件提供了bar: string
prop。因此,Foo=with Bar(FooBar)
组件应该有propsfoBarProps
,不包括bar
,这意味着只有{foo: string}
。然而TypeScript显然仍然认为Foo
组件也应该获得foo
属性。
我使用Typescript 3.3。1.
import * as React from "react";
interface FooBarProps {
foo: string;
bar: string;
}
class FooBar extends React.PureComponent<FooBarProps> {
public render() {
return <>{this.props.foo} {this.props.bar}</>;
}
}
export function withBar<TProps>(
WrappedComponent: React.ComponentType<TProps & {bar: string}>
) {
return class WithBar extends React.PureComponent<TProps> {
public render() {
return <WrappedComponent
{...this.props}
bar={"BAR"}
/>;
}
};
}
const Foo = withBar(FooBar);
// Typescript complains here:
// Error:(29, 14) TS2741: Property 'bar' is missing in type
// '{ foo: string; }' but required in type 'Readonly<FooBarProps>'.
const foo = <Foo foo="FOO" />;
我最终找到的最佳解决方案是:
export function withBar<TProps extends {bar: string}>(
WrappedComponent: React.ComponentType<TProps>
) {
return class WithBar extends React.PureComponent<
Pick<TProps, Exclude<keyof TProps, "bar">> // = Omit<TProps, "bar">
> {
public render() {
return <WrappedComponent
{...this.props as any /* still can't do better than using any here */}
bar={"BAR"}
/>;
}
};
}
其思想是,泛型参数TProps
包含我想要从结果组件中排除的属性/ie,并且我在结果组件的类型签名中手动排除它们。
唯一的警告是,TypeScript无法确定传递给包装组件的{...this.props}
具有适当的类型,所以我不得不使用any
,但幸运的是,它只影响组件的内部所有暴露在外的类型都应该是准确的。
Typescript错误消息在那里也变得非常疯狂,因此我无法调试原因:TS2322:Type'Readonly
Pick
和Exclude
类型在这里有帮助:
interface Foo{
woo: string
doo: number
}
interface Goo{
doo: number
}
type FooExcludeGoo = Pick<Foo, Exclude<keyof Foo, keyof Goo>> // {woo:string}
像下面这样的东西怎么样,它是有效的,但可能不能完全回答你的问题。https://codesandbox.io/embed/peaceful-star-194g5?fontsize=14
它的要点是将Foo和Bar分成不同的类型,并将它们连接在一起作为包装组件。如果你不想参观沙盒,下面是代码:
import * as React from "react";
interface BarProps {
bar: string;
}
interface FooProps {
foo: string;
}
type FooBarProps = FooProps & BarProps;
class FooBar extends React.PureComponent<FooBarProps> {
public render() {
return (
<>
{this.props.foo} {this.props.bar}
</>
);
}
}
export function withBar<TProps>(
WrappedComponent: React.ComponentType<TProps & BarProps>
) {
return class WithBar extends React.PureComponent<TProps> {
public render() {
return <WrappedComponent {...this.props} bar={"BAR"} />;
}
};
}
const Foo = withBar(FooBar);
// Typescript complains here:
// Error:(29, 14) TS2741: Property 'bar' is missing in type
// '{ foo: string; }' but required in type 'Readonly<FooBarProps>'.
export const Foof = () => <Foo foo="FOO" />;
问题内容: 我正在使用Typescript为我的React项目编写一个高阶组件,这基本上是一个函数,它接受React组件作为参数并返回一个环绕它的新组件。 然而,正如预期的那样,TS抱怨“导出函数的返回类型具有或正在使用私有名称” Anonymous class”。 有问题的功能: 该错误是合理的,因为未导出包装器函数的返回类,而其他模块导入则该函数无法知道返回值是什么。但是我无法在此函数外部声明
我正在用TypeScript编写一个React高阶组件(HOC)。HOC应该比包装组件多接受一个道具,所以我写了以下内容: 换句话说,是一个生成实际hoc的函数。这个HOC(我相信)是一个接受
本文向大家介绍react高阶组件添加和删除props,包括了react高阶组件添加和删除props的使用技巧和注意事项,需要的朋友参考一下 唠叨几句啦 在看程墨老师的深入浅出高阶组件,开头一点提了一个需要,创建两个高阶组件,一个能给传入的元素自定义添加props,一个是删除特定的props。我刚刚做了一下,发现高阶组件需要区分好传入的是class还是react element, 同时也需要注意好r
反应组分 如何在组件中声明输入组件?
本文向大家介绍React.js中的高阶组件,包括了React.js中的高阶组件的使用技巧和注意事项,需要的朋友参考一下 高阶部分简称为hoc。这是一种接收组件并返回具有附加功能的新组件的模式。 // hoc是自定义JavaScript函数的名称 我们使用带有状态和/或道具的组件来构建UI。hoc用类似的方法从提供的组件中构建一个新组件。 使用hoc在React中成为一个横切关注点。这些组件将负责单
本文向大家介绍写一个react的高阶组件并说明你对高阶组件的理解相关面试题,主要包含被问及写一个react的高阶组件并说明你对高阶组件的理解时的应答技巧和注意事项,需要的朋友参考一下 定义高阶组件 import React, { Component } from 'react'; const simpleHoc = WrappedComponent => { console.log('simple