首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >typescript-exercises(十四)

typescript-exercises(十四)

作者头像
阿超
发布2024-11-10 10:29:27
发布2024-11-10 10:29:27
9900
代码可运行
举报
文章被收录于专栏:快乐阿超快乐阿超
运行总次数:0
代码可运行

人心就是立国的大根本。——孙中山

问题:

代码语言:javascript
代码运行次数:0
运行
复制
/*

Intro:

    For some unknown reason most of our developers left
    the company. We need to actively hire now.
    In the media we've read that companies that invent
    and publish new technologies attract more potential
    candidates. We need to use this opportunity and
    invent and publish some npm packages. Following the
    new trend of functional programming in JS we
    decided to develop a functional utility library.
    This will put us on the bleading edge since we are
    pretty much sure no one else did anything similar.
    We also provided some jsdoc along with the
    functions, but it might sometimes be inaccurate.

Exercise:

    Provide proper typing for the specified functions.

Bonus:

    Could you please also refactor the code to reduce
    code duplication?
    You might need some excessive type casting to make
    it really short.

*/

/**
 * 2 arguments passed: returns a new array
 * which is a result of input being mapped using
 * the specified mapper.
 *
 * 1 argument passed: returns a function which accepts
 * an input and returns a new array which is a result
 * of input being mapped using original mapper.
 *
 * 0 arguments passed: returns itself.
 *
 * @param {Function} mapper
 * @param {Array} input
 * @return {Array | Function}
 */
export function map(mapper, input) {
    if (arguments.length === 0) {
        return map;
    }
    if (arguments.length === 1) {
        return function subFunction(subInput) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return subInput.map(mapper);
        };
    }
    return input.map(mapper);
}

/**
 * 2 arguments passed: returns a new array
 * which is a result of input being filtered using
 * the specified filter function.
 *
 * 1 argument passed: returns a function which accepts
 * an input and returns a new array which is a result
 * of input being filtered using original filter
 * function.
 *
 * 0 arguments passed: returns itself.
 *
 * @param {Function} filterer
 * @param {Array} input
 * @return {Array | Function}
 */
export function filter(filterer, input) {
    if (arguments.length === 0) {
        return filter;
    }
    if (arguments.length === 1) {
        return function subFunction(subInput) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return subInput.filter(filterer);
        };
    }
    return input.filter(filterer);
}

/**
 * 3 arguments passed: reduces input array it using the
 * specified reducer and initial value and returns
 * the result.
 *
 * 2 arguments passed: returns a function which accepts
 * input array and reduces it using previously specified
 * reducer and initial value and returns the result.
 *
 * 1 argument passed: returns a function which:
 *   * when 2 arguments is passed to the subfunction, it
 *     reduces the input array using specified initial
 *     value and previously specified reducer and returns
 *     the result.
 *   * when 1 argument is passed to the subfunction, it
 *     returns a function which expects the input array
 *     and reduces the specified input array using
 *     previously specified reducer and inital value.
 *   * when 0 argument is passed to the subfunction, it
 *     returns itself.
 *
 * 0 arguments passed: returns itself.
 *
 * @param {Function} reducer
 * @param {*} initialValue
 * @param {Array} input
 * @return {* | Function}
 */
export function reduce(reducer, initialValue, input) {
    if (arguments.length === 0) {
        return reduce;
    }
    if (arguments.length === 1) {
        return function subFunction(subInitialValue, subInput) {
            if (arguments.length === 0) {
                return subFunction;
            }
            if (arguments.length === 1) {
                return function subSubFunction(subSubInput) {
                    if (arguments.length === 0) {
                        return subSubFunction;
                    }
                    return subSubInput.reduce(reducer, subInitialValue);
                };
            }
            return subInput.reduce(reducer,subInitialValue);
        }
    }
    if (arguments.length === 2) {
        return function subFunction(subInput) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return subInput.reduce(reducer, initialValue);
        };
    }
    return input.reduce(reducer, initialValue);
}

/**
 * 2 arguments passed: returns sum of a and b.
 *
 * 1 argument passed: returns a function which expects
 * b and returns sum of a and b.
 *
 * 0 arguments passed: returns itself.
 *
 * @param {Number} a
 * @param {Number} b
 * @return {Number | Function}
 */
export function add(a, b) {
    if (arguments.length === 0) {
        return add;
    }
    if (arguments.length === 1) {
        return function subFunction(subB) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return a + subB;
        };
    }
    return a + b;
}

/**
 * 2 arguments passed: subtracts b from a and
 * returns the result.
 *
 * 1 argument passed: returns a function which expects
 * b and subtracts b from a and returns the result.
 *
 * 0 arguments passed: returns itself.
 *
 * @param {Number} a
 * @param {Number} b
 * @return {Number | Function}
 */
export function subtract(a, b) {
    if (arguments.length === 0) {
        return subtract;
    }
    if (arguments.length === 1) {
        return function subFunction(subB) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return a - subB;
        };
    }
    return a - b;
}

/**
 * 2 arguments passed: returns value of property
 * propName of the specified object.
 *
 * 1 argument passed: returns a function which expects
 * propName and returns value of property propName
 * of the specified object.
 *
 * 0 arguments passed: returns itself.
 *
 * @param {Object} obj
 * @param {String} propName
 * @return {* | Function}
 */
export function prop(obj, propName) {
    if (arguments.length === 0) {
        return prop;
    }
    if (arguments.length === 1) {
        return function subFunction(subPropName) {
            if (arguments.length === 0) {
                return subFunction;
            }
            return obj[subPropName];
        };
    }
    return obj[propName];
}

/**
 * >0 arguments passed: expects each argument to be
 * a function. Returns a function which accepts the
 * same arguments as the first function. Passes these
 * arguments to the first function, the result of
 * the first function passes to the second function,
 * the result of the second function to the third
 * function... and so on. Returns the result of the
 * last function execution.
 *
 * 0 arguments passed: returns itself.
 *
 * TODO TypeScript
 *   * Should properly handle at least 5 arguments.
 *   * Should also make sure argument of the next
 *     function matches the return type of the previous
 *     function.
 *
 * @param {Function[]} functions
 * @return {*}
 */
export function pipe(...functions) {
    if (arguments.length === 0) {
        return pipe;
    }
    return function subFunction() {
        let nextArguments = Array.from(arguments);
        let result;
        for (const func of functions) {
            result = func(...nextArguments);
            nextArguments = [result];
        }
        return result;
    };
}

报错:

代码语言:javascript
代码运行次数:0
运行
复制
index.ts(46,21): error TS7006: Parameter 'mapper' implicitly has an 'any' type.
index.ts(46,29): error TS7006: Parameter 'input' implicitly has an 'any' type.
index.ts(51,37): error TS7006: Parameter 'subInput' implicitly has an 'any' type.
index.ts(77,24): error TS7006: Parameter 'filterer' implicitly has an 'any' type.
index.ts(77,34): error TS7006: Parameter 'input' implicitly has an 'any' type.
index.ts(82,37): error TS7006: Parameter 'subInput' implicitly has an 'any' type.
index.ts(120,24): error TS7006: Parameter 'reducer' implicitly has an 'any' type.
index.ts(120,33): error TS7006: Parameter 'initialValue' implicitly has an 'any' type.
index.ts(120,47): error TS7006: Parameter 'input' implicitly has an 'any' type.
index.ts(125,37): error TS7006: Parameter 'subInitialValue' implicitly has an 'any' type.
index.ts(125,54): error TS7006: Parameter 'subInput' implicitly has an 'any' type.
index.ts(130,48): error TS7006: Parameter 'subSubInput' implicitly has an 'any' type.
index.ts(141,37): error TS7006: Parameter 'subInput' implicitly has an 'any' type.
index.ts(163,21): error TS7006: Parameter 'a' implicitly has an 'any' type.
index.ts(163,24): error TS7006: Parameter 'b' implicitly has an 'any' type.
index.ts(168,37): error TS7006: Parameter 'subB' implicitly has an 'any' type.
index.ts(191,26): error TS7006: Parameter 'a' implicitly has an 'any' type.
index.ts(191,29): error TS7006: Parameter 'b' implicitly has an 'any' type.
index.ts(196,37): error TS7006: Parameter 'subB' implicitly has an 'any' type.
index.ts(220,22): error TS7006: Parameter 'obj' implicitly has an 'any' type.
index.ts(220,27): error TS7006: Parameter 'propName' implicitly has an 'any' type.
index.ts(225,37): error TS7006: Parameter 'subPropName' implicitly has an 'any' type.
index.ts(256,17): error TS7023: 'pipe' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
index.ts(256,22): error TS7019: Rest parameter 'functions' implicitly has an 'any[]' type.
test.ts(4,20): error TS2554: Expected 2 arguments, but got 0.
test.ts(5,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(8,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(10,23): error TS2554: Expected 3 arguments, but got 0.
test.ts(11,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(14,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(17,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(20,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(22,23): error TS2554: Expected 2 arguments, but got 0.
test.ts(23,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(26,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(28,20): error TS2554: Expected 2 arguments, but got 0.
test.ts(29,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(32,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(34,25): error TS2554: Expected 2 arguments, but got 0.
test.ts(35,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(38,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(40,21): error TS2554: Expected 2 arguments, but got 0.
test.ts(41,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(44,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(46,26): error TS2554: Expected 2 arguments, but got 1.
test.ts(46,43): error TS2554: Expected 2 arguments, but got 1.
test.ts(46,56): error TS2554: Expected 3 arguments, but got 2.
test.ts(47,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.
test.ts(49,30): error TS2554: Expected 2 arguments, but got 1.
test.ts(49,47): error TS2554: Expected 2 arguments, but got 1.
test.ts(50,12): error TS2344: Type 'false' does not satisfy the constraint 'true'.

答案:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档