[英]Typescript: How to defined type of object key for generic type
我有一些像下面这样的代码。 我编写了带有泛型类型的自定义钩子,用于定义我的钩子的自定义类型返回。
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;
我的通用类型T
是对象。 但是当我遍历这个时,我得到这个错误Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'.
如何为泛型类型T
定义键类型? 请帮我。
所以Object.keys
函数不是通用参数化的,因此 forEach 中的v
始终是字符串。 这是推理原因 - 为什么 Object.keys 不返回 TypeScript 中的 keyof 类型? .
那就是说你不能缩小v
类型,它只是字符串。 你可以做的是类型断言:
Object.keys(input).forEach((v) => input[v as keyof T] = '')
但是您将收到下一个错误,因为您没有将T
所有值定义为字符串,并且您将空字符串分配给它。 这实际上是正确的错误。 您不能为未知对象的每个字段分配一个字符串。
为了修复第二个我们需要缩小T
的值类型
function useInput<T extends Record<string, string>>(): Return<T>
我们说现在T
有钥匙的,哪些是值string
或亚型string
。 因为它们可以是字符串的子类型,所以我们需要在之后进行第二个断言。 为什么 - 子类型可以是例如'a' | 'b'
'a' | 'b'
等类型不能取空字符串值。
Object.keys(input).forEach((v) => (input[v as keyof T] as string) = '')
但是如果不说明T extends Record<string, string>
我们将无法将此类的属性类型断言为string
。
正如我之前所说,这样的实现有问题,它有风险,如果你有对象,例如type A { a: 'x' | 'y'}
type A { a: 'x' | 'y'}
并将其传递给这样的构造,然后您可以在属性a
获得空字符串,这是A
类型A
无效成员。 但是如果你使用只有string
值的类型,我假设你这样做了,那么它完全没问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.