gpt4 book ai didi

具有索引类型的 TypeScript 通用柯里化(Currying)函数

转载 作者:搜寻专家 更新时间:2023-10-30 20:59:38 24 4
gpt4 key购买 nike

我创建了一个 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...

最后一行报错:

error TS2345: Argument of type '"name2"' is not assignable to parameter of type '"name" | "age"'.

这正是我想要的,因为属性 name2作为第二个参数给出的对象不存在。

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

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的相关部分单子(monad):

class Maybe<A> {
static of<A>(x: A): Maybe<A> {
return new Maybe(x);
}

...
}

如何正确输入 safeProp函数以及为什么我需要将其返回类型指定为 Maybe<{}>而不是 Maybe<T[K]>

最佳答案

const safeProp = <T extends Dict, K extends keyof Dict>(p: K) => (obj: T): Maybe<{}> => compose2(Maybe.of, prop(p))(obj);

上面的代码不会给你一个错误,我会试着解释为什么(以及为什么你的代码会)。

K extends keyof Dict 恰好是 nameage(这仅是函数 prop 允许的参数) .和K extends keyof T 实际上可以是 any number | 类型的键 |字符串 |符号。因为如果 T extends Dict,这并不意味着它不能有任何其他键,如“lastname”等。换句话说:

type IsDict = {name: string, age: number, lastname: string} extends Dict ? true : false // IsDict is true

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

也就是说, typescript 目前 does not have将类型参数限制为精确类型的方法(有 workarounds 但遗憾的是它们不适合您的情况)。

关于具有索引类型的 TypeScript 通用柯里化(Currying)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53824319/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com