Typescript array.map无法正确分配相交类型

问题描述 投票:1回答:2

我有一个类型为object[] & Tree[]的数组,但是arr.map(child => ...)推断子类型为object而不是object & Tree

没有其他方法可以避免这种情况吗?

[值得注意的是Tree扩展了object,但打字稿似乎没有意识到这一点,并且将交叉点类型的两个部分合并了。

编辑-最小可复制示例:

这是人为的,但基于我最近的另一个问题Transform a typescript object type to a mapped type that references itself

interface BasicInterface {
    name: string;
    children: object[];
}

function getBasic<T extends object>(input: T): BasicInterface {
    return input as BasicInterface;
}

export const basicTree = getBasic({
    name: 'parent',
    children: [{
        name: 'child',
        children: []
    }]
});

关键是下面的代码可以访问“ basicTree”及其推断的类型。对于这个例子,我定义了BasicInterface,但实际上这是自动生成的,我还没有找到一种编程方式生成一个递归接口。

我想在原始接口定义的基础上添加子代的递归类型。

而不是在代码中完全重新定义BasicInterface,因为这可能是很多样板,我正在尝试使用正确的递归定义来“增强” basicTree类型的定义。

但是当获得孩子的类型时,这种情况会下降。也许有一个更简单的解决方案?

type RestoredInterface = typeof basicTree & {
    children: RestoredInterface[]
};

function getTree(basic: BasicInterface): RestoredInterface {
    return basic as RestoredInterface;
}

const restoredTree = getTree(basicTree);

const names = restoredTree.children.map(child => child.name);
typescript intersection array-map mapped-types
2个回答
1
投票

我找到了一个奇怪的解决方案。只需更改声明中的顺序即可。这很奇怪,但是有效:

type RestoredInterface = {
    children: RestoredInterface[]
} & typeof basicTree;

编辑:这是explanation

更好的解决方案可以是这样的:

type RestoredInterface = Omit<typeof basicTree, 'children'> & {
    children: RestoredInterface[]
};

请参见Playground


0
投票

基于jcalz的观察,实际上可以简单地扩展原始接口。我很困惑,因为它是以编程方式定义的,但是如果您先命名它,这不是问题:

type BasicTreeInterface = typeof basicTree;

interface RestoredInterface extends BasicTreeInterface {
    children: RestoredInterface[]
};

const restoredTree = getTree(basicTree);

const names = restoredTree.children.map(child => {
    // Child is of type RestoredInterface
});
© www.soinside.com 2019 - 2024. All rights reserved.