如何聚合作为函数聚合的对象的所有参数类型?
how to aggregate all param types of an object which is an aggregation of functions?
请看一下这个打字稿代码:
type params1 = {p:number} ;
type params2 = {p:boolean};
type params3 = {p:string};
type res = {r:string};
const fObject = {
a:(a:params1):res=>{return {r:`${a.p}`}},
b:(a:params2):res=>{return {r:`${a.p?1:0}`}},
c:(a:params3):res=>{return {r:a.p}}
}
我们如何创建如下所示的类型:
输入参数 = 参数 1 |参数2 |参数 3
我正在创建一个新对象,它将是 fObject
的所有函数,但 运行 将是每个函数结果的记录器函数
像这样:
const loggingObject: typeof fObject = Object.keys(fObject).reduce(
(result: any, key: string) => {
result[key] = (args: any/*reason for Q*/) => logger.report(fObject
[key as loggingObject](args /*If i put something like 2 it says it has no properties in common with params1 & param2 & param3, thats why I know its possible*/));
return result;
},
{},
);
我不想要 any 类型,我需要一个动态类型,它可以接受一个带有函数的对象,并给出对象中所有函数的所有参数类型的联合
好问题。这 是 可能的——有多种方式!
在此解决方案中,我们将使用以下技术:
如果您想深入了解一下并且我的解释不够连贯,这些链接可能会有所帮助。最后我们将得到一个像这样工作的类型:
// your code here...
type MyParams = ParamForKeys<typeof fObject>;
// => `type MyParams = param1 | param2 | param3`
所以我们要做的是映射fObject
的键,并用其函数的参数类型替换每个键。键映射如下所示:
type MyParams<T> = { [key in keyof T]: ... }
现在我们要提取参数类型。这将使用条件类型。条件类型允许我们使用 infer
键:
type UnwrapPromise<T> = T extends Promise<infer Inner> ? Inner : never;
type A = UnwrapPromise<Promise<number>> // => number
type B = UnwrapPromise<number> // => never
这正是我们要使用的方法:
type GetFirstParam<T> = T extends ((param: infer Param) => any) ? Param : never
现在如果我们一起构建它,我们将得到:
type GetFirstParam<T> = T extends ((param: infer Param) => any) ? Param : never
type ParamForKeys<T> = { [key in keyof T]: GetFirstParam<T[key]> }
但这给了我们以下类型:
type MyParams = ParamForKeys<typeof fObject>;
// { a: param1, b: param2, c: param3 }
要以联合格式 (param1 | param2 | param3
) 取回值,我们可以像这样访问它们:
type GetFirstParam<T> = T extends ((param: infer Param) => any) ? Param : never
type ParamForKeys<T> = { [key in keyof T]: GetFirstParam<T[key]> }[keyof T]
这就是解决方案。
请记住,我不确定这个解决方案是否是您正在寻找的解决方案:就您的日志记录情况而言,{a: param1, b:param2}
对我来说更有意义,但这是您问题的解决方案!
请看一下这个打字稿代码:
type params1 = {p:number} ;
type params2 = {p:boolean};
type params3 = {p:string};
type res = {r:string};
const fObject = {
a:(a:params1):res=>{return {r:`${a.p}`}},
b:(a:params2):res=>{return {r:`${a.p?1:0}`}},
c:(a:params3):res=>{return {r:a.p}}
}
我们如何创建如下所示的类型:
输入参数 = 参数 1 |参数2 |参数 3
我正在创建一个新对象,它将是 fObject
的所有函数,但 运行 将是每个函数结果的记录器函数
像这样:
const loggingObject: typeof fObject = Object.keys(fObject).reduce(
(result: any, key: string) => {
result[key] = (args: any/*reason for Q*/) => logger.report(fObject
[key as loggingObject](args /*If i put something like 2 it says it has no properties in common with params1 & param2 & param3, thats why I know its possible*/));
return result;
},
{},
);
我不想要 any 类型,我需要一个动态类型,它可以接受一个带有函数的对象,并给出对象中所有函数的所有参数类型的联合
好问题。这 是 可能的——有多种方式! 在此解决方案中,我们将使用以下技术:
如果您想深入了解一下并且我的解释不够连贯,这些链接可能会有所帮助。最后我们将得到一个像这样工作的类型:
// your code here...
type MyParams = ParamForKeys<typeof fObject>;
// => `type MyParams = param1 | param2 | param3`
所以我们要做的是映射fObject
的键,并用其函数的参数类型替换每个键。键映射如下所示:
type MyParams<T> = { [key in keyof T]: ... }
现在我们要提取参数类型。这将使用条件类型。条件类型允许我们使用 infer
键:
type UnwrapPromise<T> = T extends Promise<infer Inner> ? Inner : never;
type A = UnwrapPromise<Promise<number>> // => number
type B = UnwrapPromise<number> // => never
这正是我们要使用的方法:
type GetFirstParam<T> = T extends ((param: infer Param) => any) ? Param : never
现在如果我们一起构建它,我们将得到:
type GetFirstParam<T> = T extends ((param: infer Param) => any) ? Param : never
type ParamForKeys<T> = { [key in keyof T]: GetFirstParam<T[key]> }
但这给了我们以下类型:
type MyParams = ParamForKeys<typeof fObject>;
// { a: param1, b: param2, c: param3 }
要以联合格式 (param1 | param2 | param3
) 取回值,我们可以像这样访问它们:
type GetFirstParam<T> = T extends ((param: infer Param) => any) ? Param : never
type ParamForKeys<T> = { [key in keyof T]: GetFirstParam<T[key]> }[keyof T]
这就是解决方案。
请记住,我不确定这个解决方案是否是您正在寻找的解决方案:就您的日志记录情况而言,{a: param1, b:param2}
对我来说更有意义,但这是您问题的解决方案!