Typescript 如何获取对象中函数的include参数?

Typescript 如何获取对象中函数的include参数?,typescript,Typescript,我有这样的数据 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(

我有这样的数据

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.
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))
没有拉姆达的例子

let { compose, mapObjIndexed } = require('ramda')
const inc = (n: number) => n + 1
const inc2 = (n: number, count = 2) => n + count
const g = {
    inc,
    inc2,
}
const inc3 = (n: number) => n + 3
const g2: any = Object.keys(g).reduce(
    (previousValue, key) => {
        console.log('props', previousValue, key)
        return {
            ...previousValue,
            [key]: (...arg: any[]) => { return inc3(g[key](...arg)) },
        }
    },
    {})
// const g2 = mapObjIndexed((action: any) => compose(inc3, action))(g)


// => So you can use
// But in this case g2 is any, so I have to define type of g2.
// How can I define type of g2(in this case any) depend on the g
console.log('>>', g2.inc(2), g2.inc2(5)) // 6 and 10
在这两个例子中,g2的类型是任意的,我想定义g2的类型取决于g。
如何才能做到这一点?

我们可以使用映射类型和条件类型来更改对象中每个函数的返回类型:

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 

如何转换?预期结果是什么?@TitianCernicova Dragomir使用相同类型的数据,但使用keyofWell为什么要使用
记录
?为什么不直接返回
T
,您是否需要选择某些道具?因为我想处理convertData的结果,在这种情况下是num+1 | num+2,但另一种情况是不同的?对不起,我仍然不清楚,您是否可以提供与传递的I参数类型不同的预期输出?
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