我在 React with TypeScript 中竞标并作为道具传递的函数类型是什么?



我已经创建了一个自定义的Checkbox组件。

项目中的TypeScript不接受any类型,因此我需要指示handleCheckbox()函数(位于FilterBox组件中(的确切类型,该函数将作为道具传递给子组件Checkbox

const handleCheckbox = (state: Record<string, unknown>) => {
const _preProcessNewState = { ...globalStatus, ...state };
//Change the States
setGlobalStatus(_preProcessNewState);
};

下面我们将此函数传递给复选框:

<Checkbox
text={t(TranslationConstants.Map.asapOrderInFilter)}
property={t(TranslationConstants.Map.checkboxAsapProperty)}
checked={globalStatus['asap']}
fn={handleCheckbox.bind(this)}
/>

现在,在复选框组件中,我需要声明fn((的正确类型:

import { useState, useEffect } from 'react';
type checkboxProps = {
text: string;
checked: boolean;
fn: (e: any) => void;
property: string;
};
const CheckBox = (props: checkboxProps) => {
const { text, checked, fn, property } = props;
const [statusCheck, setStatusCheck] = useState(checked);
const handleChange = () => {
const _newState = !statusCheck;
setStatusCheck(_newState);
fn({ [property]: _newState });
};
useEffect(() => {
setStatusCheck(checked);
}, [checked]);
return (
<div>
{' '}
<label>
{' '}
<input
type="checkbox"
checked={statusCheck}
onChange={handleChange}
/>{' '}
{text}
</label>{' '}
</div>
);
};
export default CheckBox;

我试过HTMLInputElement,React.HTMLInputElement,但没用。

如果您需要更多上下文,下面是完整的代码:https://codesandbox.io/s/quizzical-gould-d4bry?file=/src/App.tsx

除此之外,我还需要修复OrderList中的任何类型。如果存在任何类型,则所有构建都会中断,因此声明正确的类型至关重要。

我需要指示handleCheckbox((函数的确切类型(位于FilterBox组件中(,我将其作为道具传递给子组件Checkbox

我想你的意思是,你需要改进checkboxProps["fn"]的定义(这是你将handleCheckbox传递给的道具(,以避免使用any:

type checkboxProps = {
text: string;
checked: boolean;
fn: (e: any) => void;
// It throws warning here. Here is where I need to indicate type for e: and returning value (not sure if it's void)
property: string;
};

我尝试过HTMLInputElement,React.HTMLInputElement

如果fn道具函数作为<input>的事件监听器被直接调用,本可以处于正确的轨道上。

但是您有一个介于两者之间的handleChange函数,它以不同于简单事件侦听器的方式调用fn

<input
type="checkbox"
checked={statusCheck}
onChange={handleChange}
/>
const handleChange = () => {
const _newState = !statusCheck;
setStatusCheck(_newState);
fn({ [property]: _newState });
};

handleChange函数不使用您的事件参数,因此实际上不需要查找此类事件类型。

它使用1个参数{ [property]: _newState }调用fn道具函数,该参数的类型为Record<string, boolean>

因此,您可以将fn道具定义为:fn: (newState: Record<string, boolean>) => void;

还可以进一步定义类型,以指示它有一个由property道具字符串定义的成员,但这将在几个地方涉及泛型。

另一方面,在我看来,您的checkboxProps类型比它可能的更复杂:您正在传递一个属性名称,该名称仅用于构建一个要传递给fn道具回调的特定对象。在这种情况下,更简单的做法是直接向它传递空的新检查值,并让回调处理其对象和属性名称,这是父组件已知的(在您的情况下是FilterBox(。这样,就可以避免传递property字符串,并打破FilterBoxCheckbox之间的强耦合:现在您的Checkbox组件可以与其他父组件一起使用,这些组件可能不使用任何对象状态。

type checkboxProps = {
text: string;
checked: boolean;
fn: (newIsChecked: boolean) => void;
};
// In Checkbox component
const handleChange = () => {
const _newState = !statusCheck;
setStatusCheck(_newState);
fn(_newState);
};
// In FilterBox component (or any other parent component)
<Checkbox
text={t(TranslationConstants.Map.asapOrderInFilter)}
checked={globalStatus['asap']}
fn={(newIsChecked) => {
handleCheckbox({
asap: newIsChecked
});
}}
/>

然后,如果您想避免在多次使用具有不同属性名称的<Checkbox>组件时手动构建回调,您可以创建一个生成函数,例如在以下行中:

function makeHandleCheckboxFnForProperty(propertyName: string) {
return (newIsChecked: boolean) => {
handleCheckbox({
[propertyName]: newIsChecked
});
}
}

然后在您的模板中:

<Checkbox
text={t(TranslationConstants.Map.asapOrderInFilter)}
checked={globalStatus['asap']}
fn={makeHandleCheckboxFnForProperty('asap')}
/>

最新更新