基本上,对于我的用例,假设我们有这些函数
const fn1 = ({level, type}) => { console.log(level,type)}
const fn2 = ({level, username}) => { console.log(level,username)}
const fn3 = ({level, age}) => { console.log(level,age)}
现在我有两个组件调用这些函数,
const Component1 = () => {
const {level} = useGetUserInfo();
useEffect((fn1({level, type: 1})) => {}, [])
}
const Component2 = () => {
const {level} = useGetUserInfo();
useEffect((fn2({level, username: 'username'})) => {}, [])
useEffect((fn3({level, age: '27'})) => {}, [])
}
因此,正如您所看到的,获取级别的部分在两个组件之间是相同的,我不希望发生这种情况(实际上,除了级别之外,还有一组从不同位置获取的公共信息,这使得代码更长,重复性更高)
因此,我想要实现的是编写一个自定义钩子,它接受fn数组并返回 Package 器fn
所以我才能这样写
const Component1 = () => {
const [returnFn1] = useWrapperFn(fn1);
useEffect((returnFn1({type: 1})) => {}, []). // --> here i dont need to pass level anymore
}
const Component2 = () => {
const [returnFn2, returnFn3] = useWrapperFn(fn2,fn3);
useEffect((returnFn2({username: 'username'})) => {}, []) // --> no need to pass in level
useEffect((returnFn3({age: '27'})) => {}, []) // --> no need to pass in level
}
到目前为止,这是我钩子**,它感谢您的帮助,为修复提供反馈**:
const useWrapperFn = <T extends any[]>(fns: ((...args: T) => void)[]) => {
const {level} = useGetUserInfo();
const returnFns = fns.map((fn) => {
return ((...args: any[]) => {
// @ts-ignore
fn({ ...args[0], level}); //-> here i inject the level
}) as (props: Omit<NonNullable<Parameters<typeof fn>[0]>, 'level'>) => void;
});
return returnFns;
};
export default useWrapperFn;
我想要的是,当我使用returnFn时,**它应该仍然对其余字段进行正确的 prop 类型检查。**例如,当我调用returnFn1而没有传入type
时,将提示TS错误。
returnFn1({type: 1}) // -> works
returnFn1() // -> will throw ts error missing type
- 当前行为**
目前JS明智,逻辑正确
对于TS lint检查,它使用组件1(仅向数组传递1个fn)
然而,对于Component2(传递多于1个fn),则TS lint将是所有函数属性的组合
这就意味着
returnFn2({username: 'username'}) // --> currently prompt that missing `age` , wherease `age` belong to fn3
returnFn3({age: '27'}) // --> currently prompt that missing `usernamse` , wherease `username` belong to fn2
那么,是否有必要修改我的useWrapperFn钩子,以便它返回的returnedFn数组具有正确的props类型
2条答案
按热度按时间pgky5nke1#
要修复useWrapperFn钩子的问题,可以使用TypeScript的实用程序类型,如Parameters和Omit。
yquaqz182#
这就是你所需要的一个强有力的类型声明:
演示:www.example.comhttps://www.typescriptlang.org/play?ssl=15&ssc=1&pln=1&pc=1#code/MYewdgzgLgBArhApgdQE4EMAOnGoGJgwC8MAPACoyIAeUiYAJhDABQsB0n6qA5hAFwx0YAJ4BtALoBKYgD4hoqZNksAZpEFjO7ctMEBvAFAwYYgNIwAloQDWiESFUxdglplQhMAmAHkAtpZQpABy4MFwADYR6ABGEYikAArc6H6IdKgQFOYSsmIADLkANDAA5PEAbogRpbIyRPIVIJYMhgC+cjBGJqCQsPowldUwHSQDQxGCAIwjhsYwvdAwqOlwqGAEzCTqEOx+WGzq9fLdJsur66wcXLzewuLSnadnMAD0rzAAAlAQALSWPDAIBW8xe6hYA203D4BQkJQmIykAG43q9fvIABa4RBWKxgABWiGAsCgWMGiCqEVBiPmbWRcxMKyga0ITJZmyEzHuSPaPMMi1gK2I8CQaCwOHwYBYYhYniglnABhgFTgiEEYDgfhiuERnXyJVlmHliq6MAgcAYIHVmu1qF1DRgU2khhWsIh8xVapg+XaUhdiDETvdJnNlsEPrp-rdp1DVu9vqAA