使用映射类型返回函数返回类型的对象

时间:2018-08-29 04:52:15

标签: typescript

我有一个函数,它将一个对象作为参数并返回一个新对象。对象参数将是返回任意类型的函数的对象,而我函数的返回类型将是与对象参数具有相同键的对象,但是值将是对象参数中各个键的返回类型

现在要抓住的是,来自object参数的函数可能会引发错误,我不想在过程中间中断执行,而是收集所有失败的键,然后引发我自己的自定义错误。 / p>

这是我到目前为止所拥有的:

type ObjectParamFn =  <T>(...arbitrary: any[]) => T | never;
type ObjectParam = { [key: string]: ObjectParamFn };
type MyMethodReturnType<T extends ObjectParam> = {
    [P in keyof T]: ReturnType<T[P]>;
}

function myMethod<T extends ObjectParam>(
    param: T
): MyMethodReturnType<T> | never {
    const returnValue = {} as MyMethodReturnType<T>;
    const errors = [];
    for (let propName in param) {
        if (param.hasOwnProperty(propName)) {
            try {
                const value = param[propName](/* arbitrary */);
                returnValue[propName] = value; // TS ERROR HERE: Type '{}' is not assignable to type 'ReturnType<T[Extract<keyof T, string>]>'.
            } catch (err) {
                errors.push(propName);
            }
        }
    }

    if (errors.length) {
        throw new Error('foo');
    }

    return returnValue;
}

我标记了我收到的TS错误的位置,但将其分成自己的一行:

Type '{}' is not assignable to type 'ReturnType<T[Extract<keyof T, string>]>'.

我觉得我已经接近解决方案,但不能完全克服最后一个难题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我能够通过消除ObjectParamFn的泛型来完成这项工作,因为在我的代码库中,我实际上知道返回类型的类,因此我将其定义为一个并从那里开始工作。

type Primitive = string | number | boolean | null;
type ObjectParamFn = (...arbitrary: any[]) => Primitive | never;
type ObjectParam = { [key: string]: ObjectParamFn };
type MyMethodReturnType<T extends ObjectParam> = {
    [P in keyof T]: ReturnType<T[P]>;
}

function myMethod<T extends ObjectParam>(
    param: T
): MyMethodReturnType<T> | never {
    let returnValue = {} as { [key: string]: any };
    const errors = [];
    for (let propName in param) {
        if (param.hasOwnProperty(propName)) {
            try {
                returnValue[propName] = param[propName]();
            } catch (err) {
                errors.push(propName);
            }
        }
    }

    if (errors.length) {
        throw new Error('foo');
    }

    return returnValue as MyReturnType<T>;
}