如何编写返回与参数相同类型的TypeScript函数?

时间:2018-09-28 23:53:14

标签: typescript

我正在编写一个TypeScript函数,该函数接受带有字符串键的对象或带有字符串键的对象数组,将键修改为驼峰形,然后返回新的对象或数组。但是,我似乎无法使这些类型正常工作。

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

function camelKeys(obj: object): object {
    const modifiedObject = {};
    Object.entries(obj).forEach(([key, value]) => {
        modifiedObject[camelCase(key)] = value;
    });

    return modifiedObject;
}

function camelcaseKeys<T extends object | object[]>(obj: T): T {
    if (Array.isArray(obj)) {
        return obj.map(camelKeys);
    }

    return camelKeys(obj);
}

但是,我得到了Type 'object' is not assignable to type 'T'.Type 'object[]' is not assignable to type 'T'.的错误。

如何调整这些功能,以便正确进行类型检查?

2 个答案:

答案 0 :(得分:2)

您正在明确地更改传入的对象的类型(例如,从{foo: string}更改为{Foo: string})。

即使可以欺骗TypeScript使其具有相同的类型(这可能只能通过健康地撒满any s来完成),但这也是一个非常糟糕的主意,因为您会在运行时。

答案 1 :(得分:0)

有两个问题要解决:

  1. 告诉TypeScript camelKeys接受某个对象,然后返回一个具有不同键但值相同的对象。
  2. 告诉TypeScript,当camelcaseKeys收到一个对象时,它将返回一个对象,而当它获得一个数组时,它将返回一个数组。

第一个问题是通过使用映射类型解决的。

declare function camelKeys<T extends object>(obj: T): SameValuesAs<T>

我们对T施加了约束-它必须扩展object。但是,返回值不仅是任何object,而且返回值与T相同。 SameValuesAs助手看起来像这样:

type SameValuesAs<T extends object> = Record<string, T[keyof T]>;

第二个问题可以通过使用重载或条件类型来解决。

declare function camelcaseKeys<T extends object>(obj: T[]): SameValuesAs<T>[];
declare function camelcaseKeys<T extends object>(obj: T): SameValuesAs<T>;