Во-первых, чтобы помочь в выводе типов при вызове p()
, давайте немного изменим определение Prop
:
type Prop = <K extends keyof any, O extends {}>(k: K, o: O) =>
K extends keyof O
? O[K]
: 'Nah';
Я только что ограничил K
, чтобы он был string | number | symbol
, чтовероятно, это то, что вы имели в виду, и имеет то преимущество, что функции типа Prop
будут выводить K
как строковые литералы вместо string
.
Основная проблема, с которой выИмеется в том, что на самом деле компилятор не может проверить, можно ли присвоить тип неразрешенному условному типу (T extends U ? X : Y
, когда T
или U
зависят от неуказанных / неферментированных параметров универсального типа).Общие функции, возвращающие условные типы, призваны упростить жизнь вызывающей стороны ; реализатор более или менее застрял, используя утверждения типа или подобное, чтобы успокоить компилятор:
const p: Prop = (k: any, o: any) => o.hasOwnProperty(k) ? o[k] : 'Nah'; // no error
Аннотация k
и o
какany
позволяет нам писать нашу собственную реализацию без жалоб компилятора.Конечно, это небезопасно, и мы должны быть очень осторожны, чтобы не лгать компилятору.Что, технически, у нас есть:
// missing optional keys
const val: { a?: number } = (1 > 2) ? { a: 1 } : {};
const oops1 = p("a", val); // definitely "Nah" at runtime,
// but number | undefined at compile time, oops!
// subtypes with unknown extra keys
interface Animal { limbs: number; }
interface Cat extends Animal { lives: number; }
const cat: Cat = { limbs: 4, lives: 9 };
const animal: Animal = cat;
const oops2 = p("lives", animal); // definitely number at runtime,
// but "Nah" at compile time, oops!
// prototype properties
const regex = /hey/;
const oops3 = p("exec", regex); // definitely "Nah" at runtime,
// but function at compile time, oops!
Это все ситуации, когда ваше предположение о том, что p
реализует Prop
, оказывается неверным.Возможно, есть и другие.Только вы знаете, если ваши варианты использования таковы, когда эти ситуации не имеют значения.Может быть, они не имеют значения, но вы должны знать об этом.
В любом случае, я надеюсь, что это поможет вам.Удачи!