Я создал каррированную функцию TypeScript, которая сначала получает имя свойства в виде строки, а затем объект для получения значения этого свойства.Я использовал тип индекса, чтобы убедиться, что я получаю сообщение об ошибке при попытке получить доступ к несуществующему свойству:
export interface Dict {
name: string;
age: number;
}
const prop = <T extends Dict, K extends keyof T>(p: K) => (obj: T): T[K] => obj[p];
prop('name')({name: 'John', age: 45}); // John
prop('name2')({name: 'John', age: 45}); // error...
В последней строке выдается ошибка:
error TS2345: Argument of type '"name2"' is not assignable to parameter of type '"name" | "age"'.
, чтоименно то, что я хочу, так как свойство name2
не существует для объекта, заданного в качестве второго аргумента.
Однако, когда я пытаюсь создать безопасную версию, используя монаду Maybe, выдается похожая ошибка:
const safeProp = <T extends Dict, K extends keyof T>(p: K) => (obj: T): Maybe<{}> => compose2(Maybe.of, prop(p))(obj);
Ошибка связана со вторым аргументом функции compose2
: prop(p)
:
Argument of type 'K' is not assignable to parameter of type '"name" | "age"'.
Что я не понимаю, так как объявил K extends keyof T
, что я предположилбыть правильной, поскольку она также работает для функции prop
.
Для справки: функция compose2
:
const compose2 = <A, B, C>(f: (b: B) => C, g: (a: A) => B): ((a: A) => C) => a => f(g(a));
и соответствующая часть Maybe
монады:
class Maybe<A> {
static of<A>(x: A): Maybe<A> {
return new Maybe(x);
}
...
}
Как правильно ввести функцию safeProp
и почему мне нужно указать тип возвращаемого значения Maybe<{}>
, а не Maybe<T[K]>
?