Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何让typescript推断间接函数参数类型?_Reactjs_Typescript_Typescript Typings_Immer.js - Fatal编程技术网

Reactjs 如何让typescript推断间接函数参数类型?

Reactjs 如何让typescript推断间接函数参数类型?,reactjs,typescript,typescript-typings,immer.js,Reactjs,Typescript,Typescript Typings,Immer.js,如何将e的类型推断为React.ChangeEvent 完整代码: import React, { useState, useCallback } from 'react'; import produce from 'immer'; type RestTuple<T extends [any, ...any[]]> = T extends [any, ...infer R] ? R : never; function useImmer<S>(initialState:

如何将
e
的类型推断为
React.ChangeEvent

完整代码:

import React, { useState, useCallback } from 'react';
import produce from 'immer';

type RestTuple<T extends [any, ...any[]]> = T extends [any, ...infer R] ? R : never;

function useImmer<S>(initialState: S | (() => S)) {
  const [s, ss] = useState(initialState);
  const immer = useCallback(<F extends (s: S, ...es: any[]) => any>(fn: F) => (...es: RestTuple<Parameters<F>>) =>
    produce(s, s => {
      fn(s as S, ...es);
    }),
    [s]
  );
  return [s, immer, ss] as const;
}

export function MyComponent() {
  const [user, set_user] = useImmer({ name: 'xialvjun', age: 30 });
  return (
    <div>
      <input type="text" value={user.name} onChange={set_user((u, e) => (u.name = e.target.value))} />
    </div>
  );
}
import React,{useState,useCallback}来自“React”;
从“伊默”进口农产品;
类型restuple=T扩展[任何,…推断R]?R:从来没有;
函数useImmer(初始状态:S |(()=>S)){
常量[s,ss]=使用状态(初始状态);
常量immer=useCallback(任意>(fn:F)=>(…es:restuple)=>
生产(s,s=>{
fn(s作为s,…es);
}),
[s]
);
返回[s,immer,ss]作为常量;
}
导出函数MyComponent(){
const[user,set_user]=useImmer({name:'xialvjun',年龄:30});
返回(
(u.name=e.target.value))}/>
);
}

您的
restuple
条件类型阻止编译器在上下文中推断回调参数,因为它需要通过
restuple
的定义进行“向后”推断

相反,我倾向于使您的函数仅在元组类型
T
中通用,如下所示:

function useImmer<S>(initialState: S | (() => S)) {
    const [s, ss] = useState(initialState);
    const immer = useCallback(<T extends any[]>(fn: (s: S, ...es: T) => void) =>
        (...es: T) =>
            produce(s, s => {
                fn(s as S, ...es);
            }),
        [s]
    );
    return [s, immer, ss] as const;
}
函数useImmer(初始状态:S |(()=>S)){
常量[s,ss]=使用状态(初始状态);
常量immer=useCallback((fn:(s:s,…es:T)=>void)=>
(…es:T)=>
生产(s,s=>{
fn(s作为s,…es);
}),
[s]
);
返回[s,immer,ss]作为常量;
}
那么,您的呼叫似乎表现得更好:

export function MyComponent() {
    const [user, set_user] = useImmer({ name: 'xialvjun', age: 30 });
    return (
        <div>
            <input type="text" value={user.name} onChange={
                set_user((u, e) => (u.name = e.target.value))} />
        </div>
    );
}
导出函数MyComponent(){
const[user,set_user]=useImmer({name:'xialvjun',年龄:30});
返回(
(u.name=e.target.value))}/>
);
}
如果您将鼠标悬停在IDE中,您将看到
e
现在根据需要推断为
React.ChangeEvent


哇,非常感谢,回答得真棒。