こういう解法もあるかと思います。
考えのベースとして、
引数の部分の型を指定したいので、それ自体を引数として公開します
(val: User) => val
を受け取る関数を作る。(Userはtypeでエイリアスがつけられているとする)
*以下のソースでは実際には引数の型を見るので、上記の書き方以外も許容されます。
ts
1 // 元のコード
2 const nativMakeObject = key => val => ( { [ key ] : val } )
3
4 // TSように作成したコード
5 const TSMakeObject = < T extends ( ... args : any [ ] ) => any , K extends string > ( func : T , key : K ) => ( val : ReturnType < T > ) => ( { [ key ] : val } )
6 // 以下は同じ意味
7 // const TSMakeObject = <T extends (...args: any[]) => any, K extends string>(func: T,key: K) => (val: ReturnType<typeof func>) => ({[key]: val})
8
9 // 使用例
10 const object101 = TSMakeObject ( String , "key" ) ( "val" ) ; // { "key": "hello" }
11 console . log ( object101 ) ;
12
13 const object2 = TSMakeObject ( String , "customKey2" ) ( 42 ) ; // error: 42 は Stringではない
14 const object3 = TSMakeObject ( Boolean , "customKey3" ) ( true ) ; // { "key": true }
15
16 type User = { name : string ; age : number } ;
17 // 本来はこう使う。Stringなどで、省略できるのはクラスがコンストラクターを生成するため、糖衣構文のようなものと考えてよい。
18 const object4 = TSMakeObject ( ( val : User ) => val , "key" ) ( { name : "Jon" , age : 22 } ) ; // { "key": {"name": "Jon" , "age": 22 }}
19 console . log ( object4 ) ;
20
21
22 console . log ( TSMakeObject ( String , "key" ) ( "val" ) ) ;
23 console . log ( nativMakeObject ( "key" ) ( "val" ) ) ;
24
25 //こっちのほうが呼び出しの際分かりやすい気がする (引数の順序を左右入れ替えているだけ)
26 // const TSMakeObject2 = <K extends string, T extends (...args: any[]) => any>(key: K, func: T) => (val: ReturnType<T>) => ({[key]: val})
27
28 // const object201 = TSMakeObject2("key", String)("val"); // { "key": "hello" }
29 // console.log(object201);
30
31
32 // 共通化などを前提にした処理が糖衣構文で埋め込まれていると、行が長くなる、式の評価順序が直感的ではないなどの理由より
33 // リプレイスの際にコードリーディングが大変になるリスクをはらんでいるため、理解して使用する
34 // function TSMakeObject3<K extends string, T extends (...args: any[]) => any>(key: K, func: T) {
35 // return function (val: ReturnType<T>) {
36 // return {[key]: val}
37 // }
38 // }
39
40 // // 使用例
41 // const object301 = TSMakeObject2("key", String)("val"); // { "key": "hello" }
42 // console.log(object301);
43