Typescript 动态规划的类型 type someObj={ a:号码, b:阵列, c:{d:string}, e:{ f:字符串, g:阵列 }, j:{ k:弦, l:数组 }, m:数组 }; 类型someGeneric=???; //预期结果 类型someObjGenericResult={ b:(项目:字符串)=>无效, e:{ g:(项:{h:string,i:Array})=>{ 一:(项目编号)=>作废 } }, j:{l:(项:字符串)=>void}, m:(项目:数组)=>(项目:字符串)=>void };
所以我想编写一个泛型代码,它将接受一个任意值,并在对象中的每个数组上执行一个函数(无论它是多么嵌套) 并且具有以下特性 =>排除所有基元(如someObj.a) =>排除没有将数组作为类型的属性的对象(如someObj.c) =>但包括以数组作为道具的对象(如someObj.j)Typescript 动态规划的类型 type someObj={ a:号码, b:阵列, c:{d:string}, e:{ f:字符串, g:阵列 }, j:{ k:弦, l:数组 }, m:数组 }; 类型someGeneric=???; //预期结果 类型someObjGenericResult={ b:(项目:字符串)=>无效, e:{ g:(项:{h:string,i:Array})=>{ 一:(项目编号)=>作废 } }, j:{l:(项:字符串)=>void}, m:(项目:数组)=>(项目:字符串)=>void };,typescript,dynamic-programming,typescript-typings,Typescript,Dynamic Programming,Typescript Typings,所以我想编写一个泛型代码,它将接受一个任意值,并在对象中的每个数组上执行一个函数(无论它是多么嵌套) 并且具有以下特性 =>排除所有基元(如someObj.a) =>排除没有将数组作为类型的属性的对象(如someObj.c) =>但包括以数组作为道具的对象(如someObj.j) =>用户对具有嵌套数组(如someObj.m)的数组进行curry 由于问题更改而更新 如果您只是想了解如何进行键入(而不是运行时代码,它将someObj的实例转换为someObjGenericResult)的实例,那
=>用户对具有嵌套数组(如someObj.m)的数组进行curry 由于问题更改而更新 如果您只是想了解如何进行键入(而不是运行时代码,它将
someObj
的实例转换为someObjGenericResult
)的实例,那么我认为以下方法可以奏效:
type someObj = {
a: number,
b: Array<string>,
c: { d: string },
e: {
f: string,
g: Array<{
h: string,
i: Array<number>
}>
},
j: {
k: string,
l: Array<string>
},
m: Array<Array<string>>
};
type someGeneric<T /* can be primitive, array or object */> = ???;
// Expected Result
type someObjGenericResult = {
b: (item: string) => void,
e: {
g: (item: { h: string, i: Array<number> }) => {
i: (item: number) => void
}
},
j: { l: (item: string) => void },
m: (item: Array<string>) => (item: string) => void
};
//hasnestedArray输出未知(表示为真)或从不(表示为假)
//取决于T是数组还是至少有一个
//已嵌套阵列自身的属性。这是一个递归定义。
//HasnestArray应该返回未知,
//HasnestArray永远不会回来。
类型hasnestedArray=T extends数组是所谓的包含所有值的数组。。。这基本上是“真实”的类型。就是所谓的不包含任何值。。。这基本上是类型的“错误”。当我执行类似布尔类型的操作时,我倾向于输出未知
/从不
为真
/假
,因为它有时使后续操作更容易
HasNestedArrays
和PickHasNestedArrays
类型用于去除您不关心的T
的所有属性。而SomeGeneric
就是您要求的类型函数。我已经在上面的评论中解释了它们的作用,但是它们的工作原理需要理解和理解。如果您理解所有的符号,并且需要更多关于某些情况下发生的事情的细节,我可以详细说明
我不确定SomeGeneric
是否正是您真正想要的,因为存在像SomeGeneric
、SomeGeneric
等边缘情况。我很确定上述定义对于大多数边缘情况都是无效的
不管怎样,我希望这有帮助。祝你好运 好计划。你的问题是什么?我不确定是否热衷于编写泛型。我正在寻找泛型本身的一些递归调用,但typescript使其非常困难。我认为你的输出someObjGenericResult
类型至少有一个输入错误。。。类型{i:(item:string)=>void}
应该是{i:(item:number)=>void}
,除非我大错特错。很抱歉@jcalz让一个难题变得更难。所以Array
应该返回(item:{a:Array,b:Array})=>{a:(item:string)=>void,b:(item:number)=>void}
,如果是someObj.m
,就应该像在编辑中一样进行货币化。如果你感冒了,就看一看。很抱歉,已经很晚了。你能编辑你的问题并在那里添加任何改进,而不是仅仅在给我的评论中吗?我不想劝阻其他人回答。事实上,我已经someObj.g
返回了由于新问题而更新的适当值。。。这真的会输出你想要的吗?如果我必须再次更改它,我不想解释什么。请解释以下两行完成了什么PickHasNestedArrays extends推断V?({}扩展V?void:{[K in keyof V]:SomeGeneric}
和[K in keyof T]:未知扩展具有嵌套数组?K:never
// HasNestedArrays<T> outputs unknown (meaning true) or never (meaning false)
// depending on whether T is an array or an object with at least one
// property that HasNestedArrays itself. This is a recursive definition.
// HasNestedArrays<{a: {b: {c: string[]}}}> should return unknown,
// HasNestedArrays<{a: {b: {c: string}}}> should return never.
type HasNestedArrays<T> = T extends Array<any> ? unknown :
T extends object ? { [K in keyof T]: HasNestedArrays<T[K]> }[keyof T] : never;
// PickHasNestedArrays<T> takes an object type T and removes any properties
// that do not pass the HasNestedArrays test.
// PickHasNestedArrays<{a: string, b: string[], c: {d: string[]}}> should return
// {b: string[], c: {d: string[]}}.
type PickHasNestedArrays<T extends object> = Pick<T,
{ [K in keyof T]: unknown extends HasNestedArrays<T[K]> ? K : never }[keyof T]
>
// SomeGeneric<T> is the type you want:
// If T is an array like U[], return a function (item: U) => SomeGeneric<U>.
// If T is an object, strip all the non-array-containing properties out
// (via PickHasNestedArrays<T>) and assign the stripped object to V.
// If V is an empty object, then return void.
// Otherwise, return a new object whose properties have the same keys K from V
// but whose values are SomeGeneric<V[K]>.
type SomeGeneric<T> = T extends Array<infer U> ?
(item: U) => SomeGeneric<U> :
T extends object ? (
PickHasNestedArrays<T> extends infer V ? (
{} extends V ? void : { [K in keyof V]: SomeGeneric<V[K]> }
) : never
) : void;
type someObjGenericResult = SomeGeneric<someObj>;