Вывод параметра типа работает лучше всего, когда у вас есть фактическое значение типа, который вы пытаетесь вывести.Наличие T2
типа возвращаемого значения функции, вероятно, будет проблемой.Если вы не вызовете myValue()
в контексте, который ожидает возвращаемого значения типа C
, мало надежды на то, что компилятор выведет C
для него ... вывод параметра типавозвращаемое значение называется контекстной типизацией , и, к сожалению, в const v = myValue(...)
отсутствует контекстный тип для v
.Это может быть что угодно.
Так какие типы у вас действительно есть значения?Поскольку вы вызываете myValue()
с параметрами prop
и obj
, первое, что нужно сделать, это дать obj
универсальный тип, такой как T
, и дать prop
другой универсальный тип, такой как K
...и выведите T
и K
из obj
и prop
соответственно.
Обратите внимание, что вы предполагаете, что prop
должен быть одним из ключей obj
, поэтому у вас есть естественное ограничение для типа K
, а именно, что оно должно расширятьсяkeyof T
.
Наконец, тип возврата вашей функции может быть получен из других типов.Предполагается, что это тип свойства T
, ключ которого - K
.Это может быть представлено как T[K]
( тип поиска ).
Вот окончательная версия функции:
const myValue = <T, K extends keyof T>(prop: K, obj: T): T[K] => {
return obj[prop];
}
Обратите внимание на сходство между этой функцией ифункция getProperty()
, упомянутая в документации для keyof
и типов поиска .Единственная разница - это порядок параметров (ну, и тот факт, что возвращаемый тип выводится вместо аннотированного .... и имя функции, я думаю).
Когда мы используем это определение myValue()
мы получаем:
interface C {
readonly c: string
}
interface TestInt {
readonly a: string
readonly b: number
readonly c: C
}
const test: TestInt = {
a: 'a',
b: 1,
c: {
c: 'c',
},
}
const v = myValue('c', test) // const v: C
, как вы хотели.
Надеюсь, это поможет;удачи!