当前位置: 首页 > 知识库问答 >
问题:

React-Typescript:排除高阶组件中的属性

和嘉澍
2023-03-14

我有一个HOC,它为包装的组件提供一个属性。

我想写的打字稿类型定义,正确地公开由这个HOC创建的组件的道具类型:基本上复制(推断)包装组件的道具类型,并删除我的HOC提供的属性。有可能吗?

在下面的示例中,我有一个HOCwith Bar,它为任何接受它的包装组件提供了bar: stringprop。因此,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" />;

共有3个答案

凌照
2023-03-14

我最终找到的最佳解决方案是:

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

闾丘书
2023-03-14

PickExclude类型在这里有帮助:

interface Foo{
    woo: string
    doo: number
}
interface Goo{
    doo: number
}


type FooExcludeGoo = Pick<Foo, Exclude<keyof Foo, keyof Goo>> // {woo:string}
曾嘉祯
2023-03-14

像下面这样的东西怎么样,它是有效的,但可能不能完全回答你的问题。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