如何用Object.keys为Valtio store的setProperties实现TypeScript类型校验
解决Valtio状态仓库setProperties方法的TypeScript类型问题
在你用Valtio实现的状态仓库中,setProperties方法里通过Object.keys遍历更新属性时,TypeScript无法自动推断键的类型,导致需要用@ts-ignore跳过检查。以下是修复这个类型问题的几种方案:
方案1:类型断言键为keyof PaymentStore
直接将Object.keys返回的字符串数组断言为PaymentStore的键数组,同时对值做类型断言:
setProperties(values: Partial<PaymentStore>) { (Object.keys(values) as Array<keyof PaymentStore>).forEach((key) => { paymentStore[key] = values[key] as PaymentStore[typeof key]; }); }
方案2:使用Object.entries遍历
用Object.entries同时获取键和值,再做类型断言,代码更直观:
setProperties(values: Partial<PaymentStore>) { Object.entries(values).forEach(([key, value]) => { paymentStore[key as keyof PaymentStore] = value as PaymentStore[keyof PaymentStore]; }); }
完整修改后的代码
import { proxy } from 'valtio'; type PaymentStore = { loading: boolean; token: string | null; id: string | null; initialized: boolean; total: number; processing: boolean; paid: boolean; isError: boolean; errMsg: null | string; }; const defaultValues: PaymentStore = { loading: false, token: null, id: null, initialized: false, total: 0, processing: false, paid: false, isError: false, errMsg: null, }; const paymentStore = proxy<PaymentStore>(defaultValues); const paymentActions = { setProperty<T extends keyof PaymentStore>(key: T, value: PaymentStore[T]) { paymentStore[key] = value; }, setProperties(values: Partial<PaymentStore>) { (Object.keys(values) as Array<keyof PaymentStore>).forEach((key) => { paymentStore[key] = values[key] as PaymentStore[typeof key]; }); }, }; // 自动补全功能不受影响 paymentActions.setProperty('loading', false); paymentActions.setProperties({ loading: true, isError: true, });
原理说明
TypeScript中Object.keys默认返回string[],无法确认这些字符串就是PaymentStore的合法键,所以需要显式断言为keyof PaymentStore数组。由于values是Partial<PaymentStore>类型,其属性值必然兼容PaymentStore对应属性的类型,因此类型断言是安全的。
内容的提问来源于stack exchange,提问作者Md. A. A. Apu
相关产品推荐
相关产品推荐

