【问题标题】:How to let typescript infer the indirect function parameter type?如何让打字稿推断间接函数参数类型?
【发布时间】:2021-07-22 20:05:51
【问题描述】:

e的类型如何推断为React.ChangeEvent<HTMLInputElement>

完整代码:

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>
  );
}

【问题讨论】:

    标签: reactjs typescript typescript-typings immer.js


    【解决方案1】:

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

    相反,我倾向于使您的函数仅在该元组类型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;
    }
    

    那么您的通话似乎表现得更好:

    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>
        );
    }
    

    如果您将鼠标悬停在 IDE 中,您会看到 e 现在根据需要推断为 React.ChangeEvent&lt;HTMLInputElement&gt;

    Playground link to code

    【讨论】:

    • 哇,非常感谢,很棒的回答。
    猜你喜欢
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 2021-01-03
    • 2021-02-15
    • 2018-11-01
    • 1970-01-01
    相关资源
    最近更新 更多