Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有索引类型的TypeScript通用curried函数_Typescript_Functional Programming - Fatal编程技术网

带有索引类型的TypeScript通用curried函数

带有索引类型的TypeScript通用curried函数,typescript,functional-programming,Typescript,Functional Programming,我创建了一个TypeScript curried函数,该函数首先接收一个属性名作为字符串,然后接收从中获取该属性值的对象。 我使用了索引类型,以确保在尝试访问不存在的属性时出错: 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(

我创建了一个TypeScript curried函数,该函数首先接收一个属性名作为字符串,然后接收从中获取该属性值的对象。 我使用了索引类型,以确保在尝试访问不存在的属性时出错:

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...
这正是我想要的,因为作为第二个参数给定的对象上不存在属性
name2

然而,当我尝试使用Maybe monad创建一个安全版本时,它给出了一个类似的错误:

const safeProp = <T extends Dict, K extends keyof T>(p: K) => (obj: T): Maybe<{}> => compose2(Maybe.of, prop(p))(obj);
我不明白,因为我声明了
K扩展了keyof t
,我认为这是正确的,因为它也适用于
prop
函数

作为参考,
compose2
功能:

const compose2 = <A, B, C>(f: (b: B) => C, g: (a: A) => B): ((a: A) => C) => a => f(g(a));
如何正确键入
safeProp
函数,以及为什么需要将其返回类型指定为
Maybe
而不是
Maybe

有详细说明Typescript在将泛型函数传递到泛型高阶函数时如何无法正确推断类型(在您的情况下,这是将
的Maybe.of
传递到
compose2

您可以通过在使用时手动填写
compose2
的类型来缓解这种情况

const safeProp = <T extends Dict, K extends keyof T>(p: K) => (obj: T) => compose2<T, T[K], Maybe<T[K]>>(Maybe.of, prop(p))(obj);
const safeProp=(p:K)=>(obj:T)=>compose2(可能是of,prop(p))(obj);
safeProp
现在具有正确的类型
const safeProp:(p:K)=>(obj:T)=>可能

看到了吗?您的代码将允许
lastname
键,而Typescript会保护您不这样做


这就是说,typescript目前是将类型参数限制为精确类型的方法(有,但不幸的是,它们不适合您的情况).

很好的解释,非常感谢!但是我接受了y2bd的答案,因为它更完整,可以指示正确的返回类型。@DannyMoerkerke好的,不客气!但是问题不在于
prop
函数吗?我想
可能
和东西无关,问题是
prop(p)
被错误突出显示。是的,主要问题是
prop
函数,但正如我所说,我还想知道为什么返回类型是
可能是
。指定
compose2
函数的类型为我解释了这一切。回答很好,谢谢。我还添加了返回类型以确保完整性:
const safeProp3=(p:K)=>(obj:T):Maybe=>compose2(Maybe.of,prop(p))(obj);
TypeScript最近合并了一个PR,它可能会在将来对这种情况进行更好的推断:太好了,谢谢!我明天会好好看看,但我猜这些是即将发布的TypeScript 3.4中传播的泛型参数?
const compose2 = <A, B, C>(f: (b: B) => C, g: (a: A) => B): ((a: A) => C) => a => f(g(a));
class Maybe<A> {
  static of<A>(x: A): Maybe<A> {
    return new Maybe(x);
  }

  ...
}
const safeProp = <T extends Dict, K extends keyof T>(p: K) => (obj: T) => compose2<T, T[K], Maybe<T[K]>>(Maybe.of, prop(p))(obj);
const safeProp = <T extends Dict, K extends keyof Dict>(p: K) => (obj: T): Maybe<{}> => compose2(Maybe.of, prop(p))(obj);
type IsDict = {name: string, age: number, lastname: string} extends Dict ? true : false // IsDict is true