我有一个类型如下,其中如果名称是除"过滤器"以外的任何类型,则"AggrEntry"和"过滤器"的类型为"Aggr".
export interface Aggr {
[name: string]: AggrEntry;
filter?: Aggr;
}
Run Code Online (Sandbox Code Playgroud)
但是,除非我改为[name: string]: AggrEntry;
,否则ts代码将无法编译[name: string]: any;
.
错误是
[ts] Property 'filter' of type 'ResponseAggregation' is not assignable to string index type 'ResponseAggregationEntry'.
Run Code Online (Sandbox Code Playgroud)
逻辑上我猜测typescript尝试分配[name: string]
到过滤器,因为过滤器本身可以映射到[name: string]
.那么我将如何构建我的接口,以便ts编译器知道"name"将永远不会"过滤".
如果定义索引器,则所有属性都必须符合接口的返回类型.您可以执行以下操作:
export interface Aggr {
[name: string]: AggrEntry |Aggr;
filter?: Aggr;
}
Run Code Online (Sandbox Code Playgroud)
这显然不理想,因为这允许除了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
Run Code Online (Sandbox Code Playgroud)
虽然我们可以按预期访问对象字段,但创建这种类型的对象有点棘手.使用该filter
字段创建对象文字将产生与原始文本类似的错误.我们可以使用Object.assign使用对象文字创建该类型的实例:
let test : Aggr = Object.assign({
foo: new AggrEntry()
}, {
filter: {
bar: new AggrEntry()
}
});
Run Code Online (Sandbox Code Playgroud)
或者我们可以创建一个专用函数来帮助创建,它使用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()
}
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
202 次 |
最近记录: |