Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何键入接收泛型联合类型数组的递归函数?(打字稿)_Javascript_Typescript_Typescript Generics - Fatal编程技术网

Javascript 如何键入接收泛型联合类型数组的递归函数?(打字稿)

Javascript 如何键入接收泛型联合类型数组的递归函数?(打字稿),javascript,typescript,typescript-generics,Javascript,Typescript,Typescript Generics,我正在编写一个函数,它将遍历一系列对象,每个对象都包含一个数组。数组中的每个项都可能有一个条件函数,用于检查是否应该添加它 在尝试了一段时间并阅读了泛型之后,我仍然被卡住了 我看到的错误:'Property'条件'/'items'/'sections'在类型'T'上不存在。 有人能帮我做这件事吗? 谢谢 类型 export interface ContractDetailBO { sections: ContractSectionBO[]; condition?: Function; }

我正在编写一个函数,它将遍历一系列对象,每个对象都包含一个数组。数组中的每个项都可能有一个
条件
函数,用于检查是否应该添加它

在尝试了一段时间并阅读了泛型之后,我仍然被卡住了

我看到的错误:
'Property'条件'/'items'/'sections'在类型'T'上不存在。

有人能帮我做这件事吗? 谢谢

类型

export interface ContractDetailBO {
  sections: ContractSectionBO[];
  condition?: Function;
}

export interface ContractSectionBO {
  items: ContractSectionItemBO[];
  condition?: Function;
}

export interface ContractSectionItemBO {
  label: string;
  condition?: Function;
}




export interface ContractBO {
  encryptedContractId: string;
}

export type AnyBO = ContractDetailBO | ContractSectionBO | ContractSectionItemBO;
递归函数


export const isOfType = <T>(
  varToBeChecked: any,
  propertyToCheckFor: keyof T
): varToBeChecked is T =>
  (varToBeChecked as T)[propertyToCheckFor] !== undefined;

export function populate<T extends AnyBO>(inputArray: T[], config: Config): T[] {
    const returnItems: T[] = [];
    inputArray.map((item: T) => {
        // include this item if the condition passes or is not defined
        if (item.condition === undefined || item.condition(config)) {
            const itemToPopulate = { ...item };

            // check type of item so we know the next array to iterate

            if (isOfType<ContractDetailBO>(item, 'sections')) {
                const nextArray: ContractSectionBO[] = populate(item.sections, config);
                itemToPopulate.sections = nextArray;
            }
            if (isOfType<ContractSectionBO>(item, 'items')) {
                const leaves: ContractSectionItemBO[] = populate(item.items, config);
                itemToPopulate.items = leaves;
            }
            returnItems.push(itemToPopulate);
        }
    });
    return returnItems;
}

const populatedBOs:ContractDetailBO = populate(myContractDetailBO, myContractBO)

导出常量类型=(
瓦托贝克:任何,
propertyToCheckFor:keyof T
):varToBeChecked是T=>
(varToBeChecked为T)[propertyToCheckFor]!==未定义;
导出函数填充(inputArray:T[],config:config):T[]{
常量返回项:T[]=[];
inputArray.map((项目:T)=>{
//如果条件通过或未定义,则包括此项
如果(item.condition==未定义| | item.condition(配置)){
const itemtopulate={…item};
//检查项的类型,以便知道下一个要迭代的数组
if(类型(项目“部分”)){
const nextArray:ContractSectionBO[]=填充(item.sections,config);
itemtopulate.sections=nextArray;
}
if(类型(项目“项目”)){
const leaves:ContractSectionItemBO[]=填充(item.items,配置);
itemtopulate.items=树叶;
}
返回项目。推送(项目填充);
}
});
归还物品;
}
常量填充BOS:ContractDetailBO=填充(myContractDetailBO,myContractBO)
您可以试试这个


export type Config = {};

export interface BaseBO {
    condition?: (config: Config) => boolean;
}

export interface ContractDetailBO extends BaseBO {
    sections: ContractSectionBO[];
}

export interface ContractSectionBO extends BaseBO {
    items: ContractSectionItemBO[];
}

export interface ContractSectionItemBO extends BaseBO {
    label: string;
}

export type AnyBO = ContractDetailBO | ContractSectionBO | ContractSectionItemBO;

function isContractDetailBO(target: AnyBO): target is ContractDetailBO {
    return (target as ContractDetailBO).sections != null;
}
function isContractSectionBO(target: AnyBO): target is ContractSectionBO {
    return (target as ContractSectionBO).items != null;
}

export function populate<T extends AnyBO>(inputArray: T[], config: Config): T[] {
    const returnItems: T[] = [];
    for (const item of inputArray) {
        // include this item if the condition passes or is not defined
        if (!item.condition || item.condition(config)) {
            const itemToPopulate = { ...item };

            // check type of item so we know the next array to iterate

            if (isContractDetailBO(itemToPopulate)) {
                const nextArray: ContractSectionBO[] = populate(itemToPopulate.sections, config);
                itemToPopulate.sections = nextArray;
            }
            if (isContractSectionBO(itemToPopulate)) {
                const leaves: ContractSectionItemBO[] = populate(itemToPopulate.items, config);
                itemToPopulate.items = leaves;
            }
            returnItems.push(itemToPopulate);
        }
    }
    return returnItems;
}

导出类型Config={};
导出接口BaseBO{
条件?:(配置:配置)=>布尔值;
}
导出接口ContractDetailBO扩展BaseBO{
章节:合同章节BO[];
}
导出接口ContractSectionBO扩展BaseBO{
项目:ContractSectionItemBO[];
}
导出接口ContractSectionItemBO扩展BaseBO{
标签:字符串;
}
导出类型AnyBO=ContractDetailBO | ContractSectionBO | ContractSectionItemBO;
函数是ContractDetailBO(目标:AnyBO):目标是ContractDetailBO{
返回(目标为ContractDetailBO).sections!=null;
}
函数为ContractSectionBO(目标:AnyBO):目标为ContractSectionBO{
返回(目标为ContractSectionBO)。项!=null;
}
导出函数填充(inputArray:T[],config:config):T[]{
常量返回项:T[]=[];
for(输入阵列的常量项){
//如果条件通过或未定义,则包括此项
如果(!item.condition | | item.condition(配置)){
const itemtopulate={…item};
//检查项的类型,以便知道下一个要迭代的数组
如果(isContractDetailBO(项目填写)){
const nextArray:ContractSectionBO[]=填充(itemtopulate.sections,config);
itemtopulate.sections=nextArray;
}
如果(是合同章节BO(项目填写)){
const leaves:ContractSectionItemBO[]=填充(itemtopulate.items,配置);
itemtopulate.items=树叶;
}
返回项目。推送(项目填充);
}
}
归还物品;
}

非常感谢@givi这很好:)我仍然觉得我在以一种过于复杂的方式处理我的问题,但这种解决方案非常好。谢谢你!