Почему TypeScript заставляет меня явно передавать undefined для аргумента, который напечатан как undefined в сигнатуре моей функции? - PullRequest
2 голосов
/ 25 мая 2019

Я младший разработчик, и мне нужна помощь.Я пытался найти проблему, но мне трудно сформулировать ее правильно.Заранее извините, если вопрос вводит в заблуждение.

Может кто-нибудь помочь мне понять, почему TypeScript вынуждает меня передавать undefined в качестве аргумента функции, когда в сигнатуре функции указан параметр undefined?

Вот что я пытаюсь сделать.Я хочу создать функцию, которая возвращает функции создателя действия, которые затем возвращают объекты действия:

interface IAction<T, P> {
    type: T;
    payload?: P;
}

const createActionCreator = <T extends string, P = undefined>(type: T) => (payload: P): IAction<T, P> => ({
    type,
    payload,
});

const THIS_IS_MY_ACTION_TYPE = '@PREFIXED/THIS_IS_MY_ACTION_TYPE';

const createTestAction1 = createActionCreator<typeof THIS_IS_MY_ACTION_TYPE, string>(THIS_IS_MY_ACTION_TYPE);

const createTestAction2 = createActionCreator<typeof THIS_IS_MY_ACTION_TYPE>(THIS_IS_MY_ACTION_TYPE);

const testAction1 = createTestAction1('some string');
// works fine

const testAction2 = createTestAction2();
// TypeScript complains that an argument was expected

Когда я вызываю createActionCreator, предоставляя оба типа T и P, TypeScript заставляет менявызвать createTestAction1 с аргументом, который соответствует типу P.Это то, что я ожидаю.

Когда я вызываю createActionCreator без , предоставляющего P, или даже если я предоставляю P как undefined явно, TypeScript заставляет менявызвать createTestAction2 с undefined в качестве аргумента.Я ожидал, что смогу вызвать его без аргументов.

Буду признателен, если кто-нибудь поможет мне понять, почему он так себя ведет и как это исправить.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 26 мая 2019

Мне удалось добиться желаемого с помощью перегрузки сигнатуры функции и аргумента payloadRequired в первом вызове, чтобы определить, следует ли возвращать внутреннюю функцию с параметром полезной нагрузки или без него:

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

export function createActionCreator<T extends IActionConstant, P = 'Please provide a type definition for the payload'>(
    type: T,
    config: { withPayload: true }
): (payload: P) => IAction<T, P>;
export function createActionCreator<T extends IActionConstant>(
    type: T,
    config: { withPayload: false }
): () => IAction<T>;
export function createActionCreator<T extends IActionConstant, P>(type: T, config: { withPayload: boolean }) {
    if (config.withPayload) {
        return function createAction(payload: P) {
            return {
                type,
                payload,
            };
        };
    }
    return function createAction() {
        return {
            type,
        };
    };
}
0 голосов
/ 25 мая 2019

Функция (payload: P) => {..} имеет один параметр, поэтому Typescript ожидает аргумент, даже если тип параметра undefined. Попробуйте сделать параметр необязательным (используя ?), а затем удалите тип = undefined по умолчанию из вашего типа param <P>.

const createActionCreator = <T extends string, P>(type: T) =>
//                                             ^ type `P` is required
    (payload?: P): IAction<T, P> => ({
    //      ^ parameter `payload` is optional
        type,
        payload, // if not provided, will be the value `undefined`
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...