🥶

【TypeScript】jsで関数がオブジェクトであることを忘れていた。

に公開

https://github.com/type-challenges/type-challenges/tree/main
typechallengesにて9.Deep Readonlyの時に間違えたので備忘録
https://github.com/type-challenges/type-challenges/blob/main/questions/00009-medium-deep-readonly/README.md

type DeepReadonly<T> = {readonly[k in keyof T] : T[k] extends Record<any, any>? 
DeepReadonly<T[k]> : T[K] }

と回答したところ

Type 'false' does not satisfy the constraint 'true'.

エラー
T[k] extends Record<any, any>のところでjsで関数はオブジェクトなのでtrueとなり、再帰部分に入ってしまっていた。

type DeepReadonly<T> = {readonly[k in keyof T] : T[k] extends Record<any, any>?
T[k] extends Function ? T[k] :DeepReadonly<T[k]> : T[k] }

にしてFunctionで分岐作ると正解した。

type testFunction<T extends Function> = T extends Record<any, any> ? 'this is Function': 'not function'

試しで上記の型作ってみると

Expect<Equal<testFunction<()=>22>, 'this is Function'>> // match

参照

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type
https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Basics
https://www.javadrive.jp/javascript/function/index10.html

Discussion