如何在React中声明“ clean-element”高阶组件的类型?

时间:2018-10-05 16:25:14

标签: reactjs typescript

当前错误:

Argument of type 'typeof TextareaAutosize' is not assignable to parameter of type 'Component<{}, {}, any>'.
  Property 'setState' is missing in type 'typeof TextareaAutosize'.

代码:

import clean from "clean-element";
import Textarea from "react-textarea-autosize";

const CleanInput = clean(Textarea);

和:

import * as React from 'react';

declare function clean<TPassedProps>(
  component: React.Component<TPassedProps>
): React.ComponentType<TPassedProps>;

export default clean;

1 个答案:

答案 0 :(得分:1)

React.Component<TPassedProps>替换React.ComponentType<TPassedProps>应该摆脱立即的错误。但是,如果您实际上想要为clean函数键入正确的字符,则要困难得多。实际上,这并不是真的可以完成,因为clean返回的组件的行为取决于您为其分配的propTypes的类型,并且TypeScript不支持跟踪对象的类型。存储在已经声明的属性中的值。相反,您必须定义一个包装器函数,该函数同时接受内部组件和propTypes对象,并计算新组件的props类型,以包含被clean剥离的props以及传递到内部组件。对于完整的解决方案,应该检查一下clean是否没有用于剥离内部组件实际需要的道具。这是我想出的:

import * as React from "react";
import * as PropTypes from 'prop-types';
import clean from "clean-element";

type RequiredKeysOf<T> =
    {[K in keyof T]-?: {[P in K]?: T[K]} extends {[P in K]: T[K]} ? never : K}[keyof T];

const ERROR_SYMBOL = Symbol();
interface Cannot_clean_required_props<K extends keyof any> {
    [ERROR_SYMBOL]: undefined;
}

function cleanWithPropTypes<TPassedProps,
    TPropTypes extends React.ValidationMap<any> &
        (keyof TPropTypes & RequiredKeysOf<TPassedProps> extends never ? {} :
            Cannot_clean_required_props<keyof TPropTypes & RequiredKeysOf<TPassedProps>>)>(
    component: React.ComponentType<TPassedProps>, propTypes: TPropTypes):
    React.ComponentType<PropTypes.InferProps<TPropTypes> &
        Pick<TPassedProps, Exclude<keyof TPassedProps, keyof TPropTypes>>> {
    let cleaned = clean(component);
    cleaned.propTypes = propTypes;
    return cleaned;
}