我有这样的数据
purrr:map_img
如何定义convertData的返回类型
在这种情况下:const data = {
inc: (num: number) => num + 1,
inc2: (num: number, count = 2) => num + count,
}
const convertData = <T, K extends keyof T>(_data: T): Record<K, number> => _data
const a = convertData(data)
a.inc(2) // << wrong, Type 'Number' has no compatible call signatures.
如果您熟悉ramda,则此示例如下所示
Record<K, number>
没有ramda的示例
let { compose, mapObjIndexed } = require('ramda')
const inc = (n: number) => n + 1
const inc2 = (n: number) => n + 2
const g = {
inc,
inc2,
}
const inc3 = (n: number) => n + 3
const g2 = mapObjIndexed((action: any) => compose(inc3, action))(g)
// But in this case g2 is any, so I have to define type of g2.
// How can I define type of g2 depend on the g?
// => So you can use
console.log('>>', g2.inc(2), g2.inc2(5))
在两个示例中,我都想定义g2的类型取决于g。 我该怎么办?
答案 0 :(得分:1)
我们可以使用映射类型和条件类型来更改对象中每个函数的返回类型:
const inc = (n: number) => n + 1
const inc2 = (n: number, count = 2) => n + count
const g = {
inc,
inc2,
}
const inc3 = (n: number) => n + 3
type ChnageReturnType<T, R> = {
[P in keyof T] : T[P] extends (...a: infer A) => any ? (...a: A) => R: never
}
type AnyReturnType<T> = {
[P in keyof T] : T[P] extends (a: any) => infer R ? R: never
}[keyof T]
function mapObject<T, R>(o: T, mapFn: (o: AnyReturnType<T>)=> R) :ChnageReturnType<T, R> {
return Object.keys(g).reduce(
(previousValue, key) => {
console.log('pore', previousValue, key)
return {
...previousValue,
[key]: (...arg: any[]) => { return inc3(g[key](...arg)) },
}
},
{}) as ChnageReturnType<T, R>
}
const g2 = mapObject(g, inc3)
console.log('>>', g2.inc(2), g2.inc2(5)) // both functions fully typed return numbers
const g3 = mapObject(g, o=> o.toString()) // o is types as number but will be typed to a union of all posible return values ()
console.log('>>', g3.inc(2), g3.inc2(5)) // both functions will return strings
您也可以只使用ChnageReturnType
类型:
const g4: ChnageReturnType<typeof g, number> = Object.keys(g).reduce(
(previousValue, key) => {
console.log('pore', previousValue, key)
return {
...previousValue,
[key]: (...arg: any[]) => { return inc3(g[key](...arg)) },
}
},
{}) as any