React TypeScript中如何通过键名正确访问state对象属性?
问题根源
products.productType的写法是固定访问products对象上名为productType的静态属性,不会将productType识别为存储动态键名的变量,因此TS会提示该属性不存在——你的state对象上本身就没有叫productType的固定字段。
另外你初始的state没显式声明类型,TS会把三个数组推导为never[]类型,后续往数组里加字符串值也会触发类型错误。
修复方案
- 先为state定义明确的类型,收窄合法的产品分类范围,避免任意字符串传入导致写入非法属性:
// 定义合法的产品分类联合类型 type ProductType = 'fruits' | 'veggies' | 'herbs'; // 定义state结构类型 interface ProductsState { fruits: string[]; veggies: string[]; herbs: string[]; } const [products, setProducts] = useState<ProductsState>({ fruits: [], veggies: [], herbs: [], });
- 修改
addProduct函数,用方括号语法实现动态属性访问,替换原来的点语法,同时把参数productType的类型收窄为上面定义的ProductType:
const addProduct = (productType: ProductType, value: string) => { setProducts((prevProducts) => ({ ...prevProducts, // 左侧计算属性名、右侧动态取值都用方括号包裹变量 [productType]: [...prevProducts[productType], value], })); }
语法说明
- 点语法(
obj.xxx)仅适用于访问对象上名称固定的属性,点后面的内容会被直接识别为固定字符串键名,不会解析变量 - 方括号语法(
obj[dynamicKey])支持传入变量、表达式作为键名,和对象字面量中你已经在用的计算属性写法[productType]: xxx逻辑完全配套,是JS/TS中动态访问对象属性的标准语法 - 将
productType的类型从宽泛的string改为明确的联合类型后,TS会自动校验你传入的分类是否合法,同时能正确推导prevProducts[productType]的类型为string[],不会再报属性不存在的错误。
内容的提问来源于stack exchange,提问作者banhmi123
相关产品推荐
相关产品推荐

