[英]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.