从对象获取值的函数的强类型

Posted

技术标签:

【中文标题】从对象获取值的函数的强类型【英文标题】:Strong types for a function getting a value from object 【发布时间】:2020-10-15 17:06:33 【问题描述】:

我有一个从对象中按键获取值的功能,它允许我在使用它时查看记录中可能键的建议。该函数从它的参数推断类型。

function get, K1 extends keyof T>(
    记录:T |不明确的,
    键1:K1
): T[K1] |不明确的

const foo =  bar: 1, baz: 2 
get(foo, 'bar') // 1, get

是否可以将其转换为无点样式,保留强类型并且不丢失建议?与此类似。

function get<T extends Record<string, any>, K1 extends keyof T>(key1: K1):
    (record: T | undefined) => T[K1] | undefined

const foo =  bar: 1, baz: 2 
get('bar')(foo) // 1, get< a: number, b: number >

显然这不起作用。我尝试了 pointfree 函数的多种变体,但我无法让它工作。 我查看了函数propramda 实现,它可以无点工作,但它不提供建议,因为它允许任何字符串作为键。

type prop = <P extends string>(key: P) => <T>(obj: Record<P, T>) => T

const foo =  bar: 1, baz: 2 
prop('bar')(foo) // 1, prop: <"bar">(key: "bar") => <T>(obj: Record<"bar", T>) => T

编辑:

为了清楚起见,我知道如果不先指定记录,我将无法获得建议。

prop('...') // no suggestions here
prop('...')(foo) // now I want suggestions

【问题讨论】:

那只是柯里化,与pointfree无关。 如果你先指定key你不能真正得到建议,你可以得到prop(foo)('bar')给你建议 是的,我想以积分方式使用它,但弄糊涂了。 【参考方案1】:

我高度怀疑这是不可能的,因为依赖关系的顺序是颠倒的。如果要先提供对象,那将不是问题。

现在您必须通过泛型手动指定对象的类型,例如:

const get = <T extends Record<K1, any>, K1 extends keyof T>(key1: K1) =>
    (record: T) => record[key1];

const foo =  bar: 1, baz: 2 
get<typeof foo, keyof typeof foo>('bar')(foo)

【讨论】:

我不确定我是否理解我想要获得建议的确切程度。即使按照我在编辑中指定的方法也不可能? @PetrD.Svoboda:是的,我认为这是不可能的。 @H.B.,如果返回类型本身是泛型的,则有可能。 好的。似乎我错过了这个问题。你是对的。【参考方案2】:

Here is it(甚至可以使用in typescript 3.3,没有要检查的旧版本):

function get<K extends keyof any>(key: K): <T extends  [key in K]: any >(x: T) => T[K] 
    return x => x[key]


const foo =  bar: 1, baz: "2" 

const x = get('bar')(foo) // number
const y = get('baz')(foo) // string

const z = get('oops')(foo) // Argument of type ' bar: number; baz: string; ' is not assignable to parameter of type ' oops: any; '

哎呀。错过了关于自动建议的要点。它们不会以这种方式工作,因为在大多数情况下应该从左到右工作,这个也不例外。

【讨论】:

以上是关于从对象获取值的函数的强类型的主要内容,如果未能解决你的问题,请参考以下文章

Java的强引用弱引用软引用和虚引用

如何在没有模型的情况下验证 MVC3 中的强类型视图

创建自定义类型的强类型化集合

iOS中的强代理(strong delegate)

TypeScript 中的强类型剩余参数

解析IOS对象指针和基础数据类型的强转