从对象获取值的函数的强类型
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 函数的多种变体,但我无法让它工作。
我查看了函数prop
的ramda
实现,它可以无点工作,但它不提供建议,因为它允许任何字符串作为键。
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; '
哎呀。错过了关于自动建议的要点。它们不会以这种方式工作,因为在大多数情况下应该从左到右工作,这个也不例外。
【讨论】:
以上是关于从对象获取值的函数的强类型的主要内容,如果未能解决你的问题,请参考以下文章