TypeScript中onChange事件仅传类型部分属性的类型定义方法
问题场景
在onChange事件处理逻辑中,需要支持仅传入状态的部分属性完成状态更新,初始实现代码如下:
type TState = { open: boolean; text: string; } let state = { open: false, text: '' } type TSetState = { payload: TState; } const setState = ({ payload }: TSetState) => { state = { ...state, ...payload } } const handleChange = (text: string) => { setState({ payload: { text } }) // ^^^^^^^ // 此处抛出类型错误 }
对应抛出的类型错误信息:
Property 'open' is missing in type '{ text: string; }' but required in type 'TState'
传入完整属性setState({ payload: { text, open: false } })可以消除报错,但需要实现仅传入部分属性也能通过校验的类型定义,尝试使用keyof TSetState实现未达到预期效果。
解决方法
报错的核心原因是TSetState中payload被标注为完整的TState类型,TypeScript会要求传入对象必须覆盖TState的所有必填属性,自然不允许只传text单字段。
直接使用TypeScript内置的Partial工具类型修改payload的类型定义即可:Partial<T>会将传入的泛型T的所有属性转换为可选属性,完全匹配状态合并时仅传入部分更新字段的场景。
修改后代码如下:
type TState = { open: boolean; text: string; } let state = { open: false, text: '' } // 仅调整payload的类型为Partial<TState> type TSetState = { payload: Partial<TState>; } const setState = ({ payload }: TSetState) => { state = { ...state, ...payload } } const handleChange = (text: string) => { // 该写法现在可以正常通过类型校验 setState({ payload: { text } }) }
如果后续需要支持嵌套对象属性的部分更新,可以自行实现递归的DeepPartial类型,当前扁平状态的场景下内置Partial已经可以满足需求。
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

