如何在React自定义useModel Hook中通过TypeScript根据Key动态推导对应Value的类型?
解决方案:让useModel的handleChange根据key动态校验value类型
当然可以实现这个需求!问题出在你当前的HandleModelChangeFn类型定义上——它把value的类型设为了T所有属性值的联合类型,导致TypeScript无法根据传入的具体key来锁定对应的value类型。我们只需要把这个函数类型改成泛型函数,就能让TypeScript在调用时自动推断出对应键的value类型。
修改步骤:
更新
HandleModelChangeFn类型定义
把原来的类型改成泛型函数,新增一个泛型参数K来代表具体的键(必须是T的键),这样value的类型就可以精确绑定为T[K]:export type HandleModelChangeFn<T> = <K extends keyof T>(key: K, value: T[K]) => void;调整
handleChange函数的实现
让handleChange函数也符合这个泛型类型,确保调用时TypeScript能正确推断K:const handleChange = useCallback(<K extends keyof T>(key: K, value: T[K]) => { setModel((prevState) => ({ ...prevState, [key]: value, })); }, []);
修改后的完整代码:
import { Dispatch, SetStateAction, useCallback, useState } from 'react'; export type HandleModelChangeFn<T> = <K extends keyof T>(key: K, value: T[K]) => void; const useModel = <T>(initialModel: T): [T, HandleModelChangeFn<T>, Dispatch<SetStateAction<T>>] => { const [model, setModel] = useState<T>(initialModel); const handleChange = useCallback(<K extends keyof T>(key: K, value: T[K]) => { setModel((prevState) => ({ ...prevState, [key]: value, })); }, []); return [model, handleChange, setModel]; }; export default useModel;
效果验证:
现在当你像之前那样调用:
interface User { name: string; age: number; } const initialModel: User = { name: '', age: 1 } const [model, handleModelChange] = useModel(initialModel); handleModelChange('age', 'John'); // TypeScript会直接报错:类型"string"不能赋值给类型"number"
TypeScript会立刻识别出类型不匹配,完美实现了你想要的动态类型校验效果。
内容的提问来源于stack exchange,提问作者Yaroslav Maydich
相关产品推荐
相关产品推荐

