[英]Typescript: Place constraint on specific lookup type of generic object type
Alright so here's the problem.好吧,问题来了。 I have the following type and function definitions:我有以下类型和函数定义:
export type compareFunction<T> = (t1: T, t2: T) => boolean
function createCompareFunctionCreator<P>(customCompare: compareFunction<P>) {
return <
T,
K extends keyof T
>(propName: K) => {
return (t1: T, t2: T) => customCompare(t1[propName], t2[propName]) as compareFunction<P>
}
}
My question is, how would place a particular constraint such that T[propName]
is of type P
?我的问题是,如何放置特定约束,使T[propName]
的类型为P
?
I've tried the following:我尝试了以下方法:
function createCompareFunctionCreator<P>(customCompare: compareFunction<P>) {
return <
T extends { [keys in keyof T]: P },
K extends keyof T
>(propName: K) => {
return (t1: T, t2: T) => customCompare(t1[propName], t2[propName]) as compareFunction<P>
}
}
But this forces ALL properties in T
to map to type P
.但这会强制T
所有属性映射到类型P
。
The problem is lack of relation between P
and T
.问题是P
和T
之间缺乏关系。 We can solve that but setting the relation.我们可以解决这个问题,但要设置关系。 Consider following code:考虑以下代码:
export type compareFunction<T> = (t1: T, t2: T) => boolean
function createCompareFunctionCreator<P>(customCompare: compareFunction<P>) {
return <
T extends Record<K, P>, // pay attention here
K extends keyof T
>(propName: K) => {
return (t1: T, t2: T) => customCompare(t1[propName], t2[propName])
}
}
T extends Record<K, P>
is saying that our type T
is an object which all properties are type of P
. T extends Record<K, P>
是说我们的类型T
是一个所有属性都是P
类型的对象。 Thanks to that we can do t1[propName]
and we know that its type of P
.多亏了这一点,我们可以做t1[propName]
并且我们知道它的类型P
。
We can achieve that by some additional typing consider:我们可以通过一些额外的输入来实现这一点,考虑:
// utility type which gives us only keys which values in T1 are T2
type OnlyKeysOfT<T1, T2> = {
[K in keyof T1]: T1[K] extends T2 ? K : never
}[keyof T1]
function createCompareFunctionCreator<P>(customCompare: compareFunction<P>) {
return <
T extends Record<K, P>,
K extends OnlyKeysOfT<T, P> = OnlyKeysOfT<T, P>,
>(propName: K) => {
return (t1: T, t2: T) => customCompare(t1[propName], t2[propName])
}
}
// below only a is correct
createCompareFunctionCreator<string>((a,b) => true)<{a: string, b: number}>('a')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.