[英]How do you curry functions with named parameters?
可以說我有一些像這樣的代碼,
const createLogger = ({
dispatch,
frame,
level,
message,
}) => {
dispatch(
actions.debugLog.push({
frame,
level,
message,
}),
)
}
如何在保留命名參數的同時理解此功能?
並使用它
const userLogger = createLogger({
dispatch: useDispatch(),
frame: "userController",
level: "Warning"
// ...potentially other top level keys
})
// user stuff happens
userLogger({ message: "User deleted profile" })()
// later
const adminUserLogger = userLogger({
frame: "adminUserController",
dispatch: adminDispatch
})
用例是在我的應用程序的某些區域調用它,減少重復的代碼。
預計arity會增長(上面只是一個例子),但我也想覆蓋某些鍵。 假設我使用一組預設鍵調用該函數,我想保留這些,但這次有一個新area
。 更復雜部分的這種增加的排列(用於currying的標准用例)。
(假設你的“工廠函數”( createLogger
)返回一個函數( log
),然后調用者使用它來記錄事件,然后我將它稱為createLogFunction
)。
(使用TypeScript):
type UseDispatch = 'auto' | true | false;
type Level = 'Warning' | 'Error';
// This interface has all the required and optional named parameters of the original `actions.debugLog.push` function:
interface LogOptions {
readonly dispatch: UseDispatch;
readonly frame: string;
readonly level: Level;
readonly message: string;
[propName: string]: any;
}
type LogFunction = ( opts: Partial<LogOptions> ) => void;
declare actions.debugLog.push: LogFunction; // so `actions.debugLog.push` has the type `LogFunction`.
// This function accepts a subset of `LogOptions` values and returns a new log function that also accepts a subset of LogOptions named parameters
function createLogFunction( factoryOpts: Partial<LogOptions>, innerLogFunc: LogFunction ): LogFunction {
return function( invokeOpts: Partial<LogOptions> ): void {
let combinedOptions: Partial<LogOptions> = {};
combinedOptions = Object.assign( combinedOptions, factoryOpts );
combinedOptions = Object.assign( combinedOptions, invokeOpts );
innerLogFunc( combinedOptions );
};
}
然后你可以像這樣使用它:
let originalLogFunction: LogFunction = actions.debugLog.push;
originalLog( { message: "foo", level: 'Warning', dispatch: 'auto' } );
let logWarning = createLogFunction( { level: 'Warning', dispatch: 'auto' }, originalLogFunction );
logWarning( { message: "bar" } );
let noDispatchWarning = createLogFunction( { dispatch: false }, logWarning );
noDispatchWarning ( { message: "qux" } );
從slebetman的回答“如何在一個未知數量的參數之間調整函數”和組合對象而不是添加數字的基本結構:
const createLogFunction = options => { function curryingLogFunction(newOptions) { if (newOptions !== undefined) { // add newOptions into options options = { ...options, ...newOptions }; return curryingLogFunction; } // dispatch isn't part of the object pushed to debugLog, so get a // version of options that doesn't include it const { dispatch: _, ...optionsWithoutDispatch } = options; // for the snippet console.log(options.dispatch, optionsWithoutDispatch); //options.dispatch( // actions.debugLog.push(optionsWithoutDispatch), //); } return curryingLogFunction; } const logUserAction = createLogFunction({ dispatch: 'useDispatch()', // string for the snippet, function in your code frame: "userController", level: "Warning" // ...potentially other top level keys }); // user stuff happens logUserAction({ message: "User deleted profile" })(); // later const logAdminAction = createLogFunction({ frame: "adminUserController", dispatch: 'adminDispatch' }); logAdminAction({ message: 'message' })({ currying: 'works' })({ frame: 'override defaults' })()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.