Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs Typescript:如何为泛型类型定义对象键的类型_Reactjs_Typescript - Fatal编程技术网

Reactjs Typescript:如何为泛型类型定义对象键的类型

Reactjs Typescript:如何为泛型类型定义对象键的类型,reactjs,typescript,Reactjs,Typescript,我有一些代码如下。我使用泛型类型编写自定义钩子,用于定义钩子的自定义类型返回 type Return<T> = [T, (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void, Record<keyof T, boolean>, () => void] function useInput<T>(): Return<T> { const [i

我有一些代码如下。我使用泛型类型编写自定义钩子,用于定义钩子的自定义类型返回

type Return<T> = [T, (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void, Record<keyof T, boolean>, () => void]


function useInput<T>(): Return<T> {
    const [input, setInput] = useState<T>({} as T);
    const [isDirty, setDirty] = useState({} as Record<keyof T, boolean>);

    const handleInputChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
        setInput({
            ...input,
            [e.target.name]: e.target.value
        });
        setDirty({
            ...isDirty,
            [e.target.name]: true
        });
    };

    const resetInput = () => {
        Object.keys(input).forEach((v) => input[v] = ''); //this line i get error
        setInput({...input});
    };


    return [input, handleInputChange, isDirty, resetInput]
}

export default useInput;
type Return=[T,(e:ChangeEvent)=>void,Record,()=>void]
函数useInput():返回{
const[input,setInput]=useState({}作为T);
const[isDirty,setDirty]=useState({}作为记录);
常量handleInputChange=(e:ChangeEvent)=>{
设置输入({
…输入,
[e.target.name]:e.target.value
});
肮脏的({
…是的,
[e.target.name]:true
});
};
常量重置输入=()=>{
Object.keys(input.forEach((v)=>input[v]='');//我得到这一行错误
setInput({…input});
};
返回[input,handleInputChange,isDirty,resetInput]
}
导出默认输入;

我的泛型类型
T
是object。但是当我循环这个时,我得到这个错误
元素隐式地具有一个'any'类型,因为类型'string'的表达式不能用于索引类型'unknown'。
我如何为泛型类型
t
定义键的类型?请帮助我。

因此
对象。键
函数不是通用参数化的,因此forEach中的
v
始终是字符串。这就是为什么-

也就是说,您不能缩小
v
的类型,它将只是字符串。您可以做的是类型断言:

 Object.keys(input).forEach((v) => input[v as keyof T] = '')
但您将得到下一个错误,因为您没有定义
t
的所有值都是字符串,并且您将空字符串赋给它。这实际上是正确的错误。不能为未知对象的每个字段指定字符串

为了解决第二个问题,我们需要缩小
T

function useInput<T extends Record<string, string>>(): Return<T>
但如果不声明
T扩展记录
,我们将无法将此类属性类型断言为
字符串

正如我在前面所说的,这种实现有一个问题,它的风险就好像您有一个对象,例如
类型A{A:'x'|'y'}
,然后您将它传递给这样的构造,那么您可以在属性
A
中获得空字符串,而这是
A
类型的无效成员。但是如果您使用的类型只有
string
值,并且我假设您有,那么就完全可以了

Object.keys(input).forEach((v) => (input[v as keyof T] as string) = '')