К сожалению, то, что вы пытаетесь сделать, немного выходит за рамки возможностей TypeScript, по крайней мере на момент написания этой статьи.Основные проблемы:
- TypeScript не сможет понять, что именно вы делаете с этой строкой.TypeScript может проверить, соответствует ли данный строковый литерал ключам объекта, но кроме этого это не может помочь.поэтому мы не можем исправить ваш
as K; // TODO autoinfer is possible?
комментарий - Вы получаете
TS7023
, потому что вы возвращаетесь в объект, и так как мы могли бы возвращаться куда угодно в объект, TypeScript не уверенгде вы собираетесь остановиться, поэтому он вынужден выводить тип возвращаемого значения как any
.
Чтобы решить # 2 выше, мы можем попробовать изменить объявление функции следующим образом:
function lookup<T, K extends keyof T>(object: T, path: string): T[K] | undefined {
Но тогда TypeScript выдаст TS2322: Type 'T[K][keyof T[K]] | undefined' is not assignable to type 'T[K] | undefined'
в нашем операторе возврата.По сути, TypeScript говорит, что «вложенные дочерние типы не совпадают с родительскими типами, поэтому то, что вы написали, неверно».
Это сказало, другие, прежде чем вы попытались это сделать, и некоторые подошли довольно близко,хотя, насколько я могу судить, не существует идеальной реализации.Вы можете прочитать некоторые различные решения здесь в этом выпуске GitHub: https://github.com/Microsoft/TypeScript/issues/12290 Большинство из них прибегают к использованию массивов, а не строк, так как тогда TypeScript может легче видеть отдельные фрагменты.
В сторону
Я хотел бы упомянуть, что проблема, которую вы пытаетесь решить, не совсем понятна в мире TypeScript.Если у вас есть определенное определение объекта, к которому вы пытаетесь получить доступ - просто получите к нему прямой доступ!Нет необходимости в дополнительном уровне косвенности.TypeScript проверит тип доступа к объекту.
Если вам нужно динамически вернуть определенное поле на более позднем этапе, вы можете создать где-нибудь анонимную функцию и позже вызвать ее, чтобы сделать это, и TypeScriptможете проверить вашу анонимную функцию.
Если вам действительно нужен динамический доступ на основе строк к случайному объекту, для которого у вас нет типизации, тогда any
на самом деле правильный тип возврата для вашего lookup
функция.Поскольку, если ваш код не имеет определенной гарантии того, что это за тип, он, вероятно, может быть чем угодно.