【问题标题】:Typescript expects undefined to be passed as argument打字稿期望未定义作为参数传递
【发布时间】:2017-12-01 05:02:01
【问题描述】:

打字稿:2.4.1

我正在尝试创建一个辅助函数来生成 redux 动作创建者。

我有什么:

interface IAction<T extends string, P = undefined> {
    type: T;
    payload: P;
}

function createAction<T extends string>(type: T): () => IAction<T, undefined>;
function createAction<T extends string = '', U = undefined, V = {}>(type: T, actionCreator: (payload: U) => V): (payload: U) => IAction<T, V>;
function createAction<T extends string>(type: T, actionCreator?: (payload?: any) => any) {
    return (payload: any) => ({
        payload,
        type,
    });
}

enum ActionType {
    INCREMENT = 'COUNTER/INCREMENT',
    DECREMENT = 'COUNTER/DECREMENT',
    ASYNC_INCREMENT = 'COUNTER/ASYNC_INCREMENT',
}

const increment = createAction(ActionType.INCREMENT, () => ({ amount: 1 }));
const incrementBy = createAction(ActionType.INCREMENT, (amount: number) => amount);

在这个例子中,我希望 increment 是一个接受 0 个参数的函数,而 incrementBy 正好接受 1 个(number)。

incrementBy 按预期工作,但 Typescript 在调用 increment()(不带参数)时抛出此错误:

[ts] Expected 1 arguments, but got 0;

尝试以与我调用 incrementBy 相同的方式调用它,例如increment(42),我收到这个错误:

[ts] Argument of type '42' is not assignable to parameter of type 'undefined';

这有效:increment(undefined)

有没有办法解决这个问题?

【问题讨论】:

    标签: typescript redux


    【解决方案1】:

    您应该简单地创建另一个重载,表示它将返回一个不带参数的函数,而不是一个将undefined 作为唯一参数的函数。

    function createAction<T extends string>(type: T): () => IAction<T, undefined>;
    function createAction<T extends string, V>(type: T, actionCreator: () => V): () => IAction<T, V>;
    function createAction<T extends string, U, V>(type: T, actionCreator: (payload: U) => V): (payload: U) => IAction<T, V>;
    function createAction<T extends string, U, V>(type: T, actionCreator?: (payload: U) => V): (payload: U) => IAction<T, V> {
        return (payload: any) => ({
            payload,
            type,
        });
    }
    

    但是,您的实现似乎对传递的函数没有任何作用。您可能想要这样做:

    function createAction<T extends string>(type: T): () => IAction<T, undefined>;
    function createAction<T extends string, V>(type: T, actionCreator: () => V): () => IAction<T, V>;
    function createAction<T extends string, U, V>(type: T, actionCreator: (payload: U) => V): (payload: U) => IAction<T, V>;
    function createAction<T extends string, U, V>(type: T, actionCreator?: (payload: U) => V): (payload: U) => IAction<T, V> {
        if (actionCreator) {
            return (payload: U) => ({
                payload: actionCreator(payload),
                type,
            });
        } else {
            return () => ({
                payload: undefined,
                type
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-26
      • 2021-06-17
      • 2017-02-15
      • 2021-06-17
      • 2023-03-30
      • 2020-06-22
      • 1970-01-01
      相关资源
      最近更新 更多