我正在使用最新的Typescript版本:2.6.2
。
我遇到了一个奇怪的情况,如果我做foo({a:1,b:2})
- 事情不起作用,而如果我这样做:foo({b:2,a:1})
- 他们确实有效。
我有一个泛型类,一个有2个属性和一个函数的接口。
以下是代码:
class MyClass<T> {
value: T;
next(value: T): void {
}
}
export enum StateKey { backlogItems='backlogItems'}
export interface State {
backlogItems : number[];
[key: string]: any
}
class A {
private subj = new MyClass<State>();
public set<T>(name: StateKey, state: T) {
this.subj.next({ backlogItems: [...this.subj.value.backlogItems] ,
[name]:state //<--- error here
})
}
}
我收到错误:
Argument of type '{ [name]: T; }' is not assignable to parameter of type 'State'. Types of property 'backlogItems' are incompatible. Type 'T' is not assignable to type 'number[]'.
但是如果我改变对象中文字的顺序:
来自:
this.subj.next({ backlogItems: [...this.subj.value.backlogItems], [name]: state })
到:
this.subj.next({ [name]:state, backlogItems: [...this.subj.value.backlogItems] })
问题
为什么更改订单会使其编译?
答案 0 :(得分:2)
如果将StateKey
enum中的字符串更改为其他值,则编译时没有错误,例如
export enum StateKey { backlogItems='somethingElse'}
(如果您向枚举添加更多值,错误也会消失)
编译器正在执行type inference并检测到[name]
函数的参数中的next()
只能backlogItems
,其被声明为number[]
。< / p>
因此,对象文字的两个变体都为同一属性分配了两个不同的值,这就是为什么赋值顺序很重要 - 最后一个基本上胜出。如果最后指定的值与声明的属性类型不兼容,编译器会报告错误 - T
与number[]
不兼容。
<强>更新强>
此外,为了保留代码并消除错误,您可以通过将name
类型分配给中间变量,使编译器忘记它为string
推断的类型:< / p>
class MyClass<T> {
value: T;
next(value: T): void {
}
}
export enum StateKey { backlogItems='backlogItems'}
export interface State {
backlogItems : number[];
[key: string]: any
}
class A {
private subj = new MyClass<State>();
public set<T>(name: StateKey, state: T) {
const key: string = name;
this.subj.next({ backlogItems: [...this.subj.value.backlogItems] ,
[key]:state
})
}
}