簡體   English   中英

你如何用命名參數curry函數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM