让我们有类A
和子类B
。我想把一个B
的数组赋给A
的数组。对于普通数组,它可以正常工作,但是对于ko.ObservableArray
,它失败了。
import ko from "knockout";
class A {};
class B extends A {b = 1};
const a: A = new B(); // no problem here
const aArr: A[] = [] as B[]; // no problem here
// COMPILER PROBLEM ON LAST LINE!
const aObs: ko.ObservableArray<A> = ko.observableArray() as ko.ObservableArray<B>;
编译器对最后一行不满意,它显示这样的错误:
Type 'ObservableArray<B>' is not assignable to type 'ObservableArray<A>'.
Types of parameters 'value' and 'value' are incompatible.
Type 'A[] | null | undefined' is not assignable to type 'B[] | null | undefined'.
Type 'A[]' is not assignable to type 'B[]'.
Type 'A' is not assignable to type 'B'.
但是很明显,我不想把A
赋给B
,而是把B
赋给A
。
如何科普呢?
1条答案
按热度按时间dxxyhpgq1#
问题是
ObservableArray<T>
是它的类型变量T
上的contravariant,这就是为什么它试图反向赋值。虽然你可以自由地将
B
赋值给A
(因为B extends A
和你甚至不必将它声明为extends
),当它进入协变位置时:playground link
您不能指定以相同方向的这些类型参数为参数的函数。只能指定相反方向的参数。
playground link
如果你确信赋值是正确的,编译器会对你进行不必要的限制,你可以自己承担责任,把它类型转换为期望的类型:
playground link
你也可以用
--strictFunctionTypes
选项全局关闭fn参数的逆变检查,尽管大多数时候这是非常有用的检查。