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) = '')