TS接受一个回调函数,该回调函数需要一个将被调用的类型的子类,但不需要一个完全独立的类型。
这对我来说似乎是个错误,这有什么作用?
伪:
class A ...
class B extends A ...
class C ...
callWithA((a:A)=>void) ...
takeB(b:B) ...
takeC(c:C) ...
callWithA(takeB) // compiles fine, but will break at runtime
callWithA(takeC) // does not compile
完整示例:
class A {
a: string;
}
class B extends A {
b: string;
}
class C {
c: string;
}
function callWithA(callbackfn: (value: A) => void): void {
callbackfn(new A());
}
function callWithB(callbackfn: (value: B) => void): void {
callbackfn(new B());
}
function takeA(a: A) {
console.log('takeA got', a);
console.log('#');
}
function takeB(b: B) {
console.log('takeB got', b);
console.log('#');
}
function takeC(c: C) {
console.log('takeC got', c);
console.log('#');
}
function takeString(s: String) {
console.log('takeString got', s);
console.log('#');
}
let a: A
a = new B();
let b: B;
// b = new A(); // incompatible, Good!
// takeB(new A()); // incompatible, Good!
callWithA(takeA); // takeA(a:A) will be called with an A, OK
callWithA(takeB); // BUG HERE ?! takeB(b:B) will be called with an A!! not good!
// callWithA(takeC); // incompatible, good, A is not a C
// callWithA(takeString); // incompatible, good
callWithB(takeA); // takeA(a:A) will be called with a B, OK
callWithB(takeB); // takeB(b:B) will be called with a B, OK
// callWithB(takeC); // incompatible, good, A is not a C
// callWithB(takeString); // incompatible, good
我希望编译器拒绝使用不兼容的回调'takeB'
我已经看到TS确实接受带有必需参数子类的调用函数,这可能会引起问题:
addDog(arr: Animal[]) {arr.append(new Dog())}
let cats: Cat[] = []
addDog(cats) // Works, since cats are animals, but then we get dogs in a array of cats
但这似乎有所不同,直接调用回调不会编译。
这是错误,还是“按设计”。
答案 0 :(得分:1)
默认情况下,函数参数是双变量的。有一个编译器标志会将其变为错误,它被称为RadioGroup
。使用此标志,您突出显示的呼叫将是一个错误。
您可以详细了解here