打字稿接口动态参数没有任何就无法编译

2023-11-23

我的类型如下,如果名称是“filter”以外的任何内容,则类型为“AggrEntry”,“filter”的类型为“Aggr”。

export interface Aggr {
    [name: string]: AggrEntry;
    filter?: Aggr;
}

但是,除非我更改,否则 ts 代码将无法编译[name: string]: AggrEntry; to [name: string]: any;.

错误是

[ts] Property 'filter' of type 'ResponseAggregation' is not assignable to string index type 'ResponseAggregationEntry'.

从逻辑上讲,我猜测打字稿试图分配[name: string]过滤,因为过滤器本身可以映射到[name: string]。那么我将如何构建我的界面,以便 ts 编译器知道“名称”永远不会是“过滤器”。


如果定义索引器,所有属性都必须符合接口的返回类型。您可以执行以下操作:

export interface Aggr {
    [name: string]: AggrEntry |Aggr;
    filter?: Aggr;
}

这显然不理想,因为这允许除filter属于类型Aggr.

另一种选择是使用type定义而不是接口,并使用交集类型:

export type Aggr  = {
    [name: string]: AggrEntry;
} & {
    filter?: Aggr;
}

let test : Aggr;
let foo = test.foo // foo is AggrEntry
test.filter // works, is of type Aggr

虽然我们可以按预期访问对象字段,但创建这种类型的对象有点棘手。使用以下命令创建对象字面量filter字段将产生与原始错误类似的错误。我们可以使用 Object.assign 使用对象文字创建该类型的实例:

let test : Aggr = Object.assign({
    foo: new AggrEntry()
}, {
    filter: {
        bar: new AggrEntry()
    }
});

或者我们可以创建一个专用函数来帮助创建,它使用Object.assign:

function createAggr(dynamicPart: {
    [name: string]: AggrEntry;
}, staticPart?: {
    filter?: Aggr;
}) {
    return Object.assign(dynamicPart, staticPart);
}

let test : Aggr = createAggr({
    foo: new AggrEntry()
}, {
    filter: {
        bar: new AggrEntry()
    }
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

打字稿接口动态参数没有任何就无法编译 的相关文章

随机推荐