#typescript #react-redux #redux-toolkit
Вопрос:
Существует функция, которая возвращает другую. Я хочу сделать параметр внутренней функции необязательным, если присутствует параметр внешней функции, и обязательным в противном случае.
function outer(a?: number) {
// How can we make b here optional if a is present and mandatory otherwise?
return function inner(b: number) {
// some stuff
};
}
Конечно, мы можем просто вернуть две функции с разными сигнатурами внутри внешней функции, но мне интересно, есть ли лучшее решение.
Обновить
Решение с перегрузкой функций работает для этого простого примера.
function outer(a: number): (b?: number) => any;
function outer(a?: number): (b: number) => any;
function outer(a?: number) {
return function inner(b?: number) {
// some stuff
};
}
outer(1)(2);
outer(1)();
outer()(1);
Как насчет реального примера с Redux:
import { AsyncThunk, createAsyncThunk } from "@reduxjs/toolkit";
type RecipeGetter = () => string[];
type ThunkWithOptionalRecipeIds = AsyncThunk<
Record<string, string>,
string[] | undefined,
Record<string, never>
>;
type ThunkWithRequiredRecipeIds = AsyncThunk<
Record<string, string>,
string[],
Record<string, never>
>;
function getFetchRecipesByIdThunk(
typePrefix: string,
recipeIdGetter: RecipeGetter,
): ThunkWithOptionalRecipeIds;
function getFetchRecipesByIdThunk(
typePrefix: string,
recipeIdGetter?: RecipeGetter,
): ThunkWithRequiredRecipeIds;
function getFetchRecipesByIdThunk(
typePrefix: string,
recipeIdGetter?: RecipeGetter,
) {
return createAsyncThunk(typePrefix, async (recipeId?: string[]) => {
// some stuff
}
}
Похоже, что здесь это не работает:
Скриншот из редактора кода с ошибкой
Ответ №1:
Вы можете сделать это с помощью перегрузок метода машинописи. Просто объявите все возможности аргументов и возвращайте значения следующим образом:
function outer(a: number): (b: number) => any;
function outer(): (b?: number) => any;
function outer(a?: number) {
return function inner(b?: number) {
// some stuff
};
}
и вы можете изменить значение any
на то, что на самом деле вернет закрытие
VSCode правильно выдает ошибку во второй строке, потому что для этого требуется аргумент
Комментарии:
1. Оп просит
function outer(a: number): (b?: number) => any;
иfunction outer(): (b: number) => any;
, противоположное тому, что у вас есть. Он должен ошибаться на первом, а не на втором.2. Перегрузка функций работает в этом простом примере. Но я допустил ошибку, когда попытался применить этот подход к более сложному делу. Я обновил свой вопрос.