85658


以下のような、オブジェクトにマップ処理する関数があります。

[code]

    const objectMap = (obj, fun) => Object.fromEntries(Object.entries(obj).map(fun));
    
    objectMap({a: 2, b: 4}, ([key, val]) => [key, val * 2]) // {a: 4, b: 8}
    
[/code]

この関数をtsで型付けしたいのですが上手く行かないです。

以下のように試して見たのですが、

[code]

    type ObjectMap = <K extends keyof O1, O1 extends Record<string, V1>, O2 extends Record<K, V2>, V1, V2>(
      obj: O1,
      fun: (arg: [K, V1]) => [K, V2],
    ) => O2;
    const objectMap: ObjectMap = (obj, fun) => {
      const a = Object.entries(obj);
      const b = a.map(fun)
      const c = Object.fromEntries(b);
    
      return c;
    };
    
[/code]

a.map(fun)の箇所で

[code]

    型 '(arg: [K, V1]) => [K, V2]' の引数を型 '(value: [string, V1], index: number, array: [string, V1][]) => [K, V2]' のパラメーターに割り当てることはできません。 ts(2345)
    
[/code]

とエラーが出てしまいました。

どのように型付けしたら良いでしょうか？


CC BY-SA 4.0
2022-01-12T11:20:57.987
85652
2022-01-12T19:48:59.110
2022-01-12T11:22:06.320
32986
50855
question
typescript
オブジェクトに対してマップ処理する関数を型付けしたい


[`Object.entries()`](https://github.com/microsoft/TypeScript/blob/0326534/lib/lib.es2017.object.d.ts#L38)
が

[code]

    entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];
    
[/code]

また、
[`Object.fromEntries()`](https://github.com/microsoft/TypeScript/blob/065a996345fcfafd3c744d2a724a1ae9f31f9ab0/lib/lib.es2019.object.d.ts#L28)
が

[code]

    fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T };
    
[/code]

と型付けされているので、逆算すると次のようになるのではないでしょうか。

[code]

    type ObjectMap = <V, R>(
      obj: { [s: string]: V } | ArrayLike<V>,
      fun: (arg: [string, V]) => [PropertyKey, R]
    ) => { [s: string]: R };
    
    const objectMap: ObjectMap = (obj, fun) =>
      Object.fromEntries(Object.entries(obj).map(fun));
    
    const result = objectMap({ a: 2, b: 4 }, ([key, val]) => [key, val * 2]); 
    console.log(result); // {a: 4, b: 8}
    
[/code]

([Playground](https://www.typescriptlang.org/play?target=6#code/C4TwDgpgBA8gRgKwgY2AWQIZigXigHgDUAaKAJQD4AKAKCigHtEAuKAbygG0BnV74AE4BLAHYBzALqtCUAL5QAPlACCAgRhAAZIQGsIRCsTpQAZgFcRrKhgFjWPQaLGlCEgJS4KXAAoCGkAVAAaQgQUjIJGg8cLw4ePkdxKXI5AG4aGmQGEX5GRBR0LFZ4JFRMbDwqJgRScxFoimMSgoA6Ez8AWwBREUcIbipm1BaIXuF+qsQ3Fo6sKjq3N3TM7NyBfrMAG2BcPNLCsCoODFYAJlI4VgAWOVIqTj0wqAA3DE33Ty5H0lfNqAAqKCndypKArHIMTYQFqbBhiKjrbhbYBLKAAejR7BOUCuF1YAA5ZDQgA))


CC BY-SA 4.0
2022-01-12T18:58:16.483
85658
2022-01-12T19:48:59.110
2022-01-12T19:48:59.110
2808
2808
85652
answer