我正在尝试在typescript中创建以下界面:
type MoveSpeed = "min" | "road" | "full";
interface Interval {
min?: number,
max?: number
}
interface CreepPlan {
[partName: string] : Interval;
move?: MoveSpeed;
}
但是,此语法无效。编译器说Property 'move' of type '"min" | "road" | "full" | undefined' is not assignable to string index type 'Interval'.
。
我正在使用编译器选项strictNullChecks:true
,这就是为undefined
键隐式包含move?
的原因。
但是,此语法有效:
type MoveSpeed = "min" | "road" | "full";
interface Interval {
min?: number,
max?: number
}
interface CreepPlan {
[partName: string] : Interval;
move: MoveSpeed; // 'move' is required
}
我想表达一个想法“CreepPlan由字符串组成:间隔对,除了可选的'move'键,它是一个字符串:MoveSpeed对。”是否有可能用打字稿表达这个?
答案 0 :(得分:4)
您声明CreepPlan
上的所有媒体资源都有Interval
- 您写下时的类型值:
interface CreepPlan {
[partName: string] : Interval;
}
即,CreepPlan
的任何字符串索引可访问属性都是Interval
。这同样适用于move
,因为foo['move']
与foo.move
相同。
然而,看Interval
,没有必要的结构:
interface Interval {
min?: number,
max?: number
}
该合同中没有必填字段,但 需要一个对象。它会很乐意接受一个空对象,但它需要一些可以具有min
和max
属性的对象。
另一方面,您的MoveSpeed
类型允许undefined
:
属性'move'类型'“min”| “道路”| “满”| undefined'不能分配给字符串索引类型'Interval'。
因此,Interval
必须是没有必需属性的对象(string
可以轻松满足)但不允许undefined
MoveSpeed
做< / em>允许。
你的类型是不相交的,但是在你解决它们一两次之前它并不明显。
答案 1 :(得分:3)
如在typescript docs中所述,如果使用可索引属性,则所有其他属性的所有返回类型都应该可以分配给索引返回类型的返回类型。
这是因为foo['bar']
和foo.bar
是相同的。
那为什么会这样呢?
interface CreepPlan {
[partName: string]: Interval;
move: MoveSpeed;
}
因为任何MoveSpeed
都是有效的Interval
值(它是未定义min
/ max
的间隔。
为什么这不起作用?
interface CreepPlan {
[partName: string]: Interval;
move?: MoveSpeed;
}
move?
的类型为MoveSpeed
,加上undefined
类型。如果is具有未定义的值,则它不能分配给Interval
,因此编译器会正确显示错误。
你怎么解决这个问题?只需使索引器具有undefined
作为有效值:
interface CreepPlan {
[partName: string]: Interval | undefined;
move?: MoveSpeed;
}