До TS 4.8 возможно получение типа значения для пути A/${number}
из { A: Record<number, boolean> }
, то есть type B = DeepValue<A/${number}> // boolean
однако невозможно получить тип значения для пути A/${123}
из { A: { 123: boolean } }
, type B = DeepValue<A/${123}> // never
В TS 4.8 Улучшенный вывод типов вывода в шаблонных строковых типах сделал возможным числовой литеральный тип пути.
type DeepKey< T, K extends keyof T = keyof T > = K extends string | number ? T[K] extends infer R ? `${K}`| (R extends Record<string, unknown> ? `${K}/${DeepKey<R>}` : never) : never // impossible route : never // impossible route type DeepValue< T, P extends DeepKey<T>, > = P extends `${infer K}/${infer Rest}` ? T[(K extends `${infer R extends number}` ? R : K) & keyof T] extends infer S ? S extends never // make S distributive to work with union object ? never : Rest extends DeepKey<S> ? DeepValue<S, Rest> : never // impossible route : never // impossible route : T[(P extends `${infer R extends number}` ? R : P) & keyof T]
поддерживать:
- вложенный
- цифровые клавиши
- союзы
"детская площадка"
У этого подхода есть один серьезный недостаток, знаете ли вы, что это такое и как его исправить? (подсказка: рушащийся путь)