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 动态规划的类型 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.a)

=>排除没有将数组作为类型的属性的对象(如someObj.c)

=>但包括以数组作为道具的对象(如someObj.j)


=>用户对具有嵌套数组(如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>;