[英]Typescript type a is not assignable to type b
I'm using konva library with Typescript which is HTML5 Canvas JavaScript framework. 我正在使用带有Typescript的konva库 ,它是HTML5 Canvas JavaScript框架。
Here is a simple tutorial code that I changed from javascript to typescript. 这是一个简单的教程代码,我从javascript更改为打字稿。
import Konva from "konva";
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
const layer = new Konva.Layer();
stage.add(layer);
const box = new Konva.Rect({
x: 50,
y: 50,
width: 100,
height: 50,
fill: '#00D2FF',
stroke: 'black',
strockWidth: 4,
draggable: true
});
layer.add(box);
But my Visual Studio Code shows error message like below. 但是我的Visual Studio代码显示如下错误消息。
Argument of type 'Rect' is not assignable to parameter of type 'Group | Shape<ShapeConfig>'.
Type 'Rect' is not assignable to type 'Shape<ShapeConfig>'.
Types of property 'hitFunc' are incompatible.
Type 'GetSet<(ctx: Context, shape: Rect) => void, Rect>' is not assignable to type 'GetSet<(ctx: Context, shape: Shape<ShapeConfig>) => void, Shape<ShapeConfig>>'.
Type '(ctx: Context, shape: Rect) => void' is not assignable to type '(ctx: Context, shape: Shape<ShapeConfig>) => void'.
Types of parameters 'shape' and 'shape' are incompatible.
Type 'Shape<ShapeConfig>' is missing the following properties from type 'Rect': _sceneFunc, cornerRadiusts(2345)
The class Shape
is in Shape.d.ts
and Rect
is in Rect.d.ts
. Shape
类在Shape.d.ts
而Rect
在Rect.d.ts
。 And I can see that Rect
extended Shape
! 我可以看到
Rect
扩展了Shape
! but VSC shows an error. 但VSC显示错误。
If I add the two property which is in Rect.d.ts
to Shape
class, the error is gone . 如果我将
Rect.d.ts
的两个属性添加到Shape
类, 则错误消失了 。
export declare class Shape<Config extends ShapeConfig = ShapeConfig> extends Node<Config> {
_sceneFunc(context: any): void; // this was in Rect class
cornerRadius: GetSet<number, this>; // this was in Rect class
...
...
I know that layer.add()
function accept only Shape
type. 我知道
layer.add()
函数仅接受Shape
类型。 But as you know Typescript allows downcasting like below. 但是,您知道Typescript允许向下转换,如下所示。
class Base {
baseProperty: string = "aaaa";
}
class A extends Base {
aProperty: number = 1;
}
var a: A = new A();
function test(arg: Base) {
console.log(arg.baseProperty);
}
test(a); // => No Error
I cannot understand why layer.add()
cannot accept Rect
type even though it extended Shape
type. 我不明白为什么
layer.add()
不能接受Rect
类型,即使它扩展了Shape
类型。 What did I miss? 我错过了什么?
I need your advice. 我需要你的建议。 Thanks.
谢谢。
The definitions for the library are apparently not tested with strictFunctionTypes
unfortunately. 不幸的是,该库的定义显然未经过
strictFunctionTypes
测试。
If this option is not activated, functions relate bivariantly, but under strictFunctionTypes
functions relate contravariantly with regard to parameter types. 如果未激活此选项,则函数是双变量的,但是在
strictFunctionTypes
下,函数在参数类型方面是strictFunctionTypes
变量的。 This means: 这意味着:
class Animal { private x:undefined }
class Dog extends Animal { private d: undefined }
type EventHandler<E extends Animal> = (event: E) => void
let o: EventHandler<Animal> = (o: Dog) => { } // fails under strictFunctionTyes
The error you are getting is on hitFunc
(and if that is fixed on sceneFunc
) these are functions that take a second parameter of this
, in effect Shape<ShapeConfig>
. 您遇到的错误是在
hitFunc
(并且如果在sceneFunc
上已sceneFunc
),这些函数采用this
函数的第二个参数,实际上是Shape<ShapeConfig>
。 And this triggers the error when we try to assign the hitFunc
in Rect
that has takes a second parameter, also typed as this
but in effect Rect
. 当我们尝试在具有第二个参数的
Rect
中分配hitFunc
时,这会触发错误,该参数也被键入为this
但实际上是Rect
。 You can't assign the function with the derived parameter type to a function signature that would accept any base type argument. 您不能将具有派生参数类型的函数分配给可以接受任何基本类型参数的函数签名。
There are multiple possible solution: 有多种可能的解决方案:
Use a type assertion 使用类型断言
layer.add(box as unknown as Shape<ShapeConfig>);
Disable strictFunctionTypes
(the error goes away with strictFunctionTypes: false
in tsconfig) 禁用
strictFunctionTypes
(该错误随strictFunctionTypes: false
)
Submit a pull request to definitely typed to make hitFunc
and sceneFunc
behave bivariantly event under strictFunctionTypes: true
as described here . 提交pull请求,肯定类型做出
hitFunc
和sceneFunc
表现下bivariantly事件strictFunctionTypes: true
的描述在这里 。 In this case this would work and preserve the functionality: 在这种情况下,它将起作用并保留功能:
export type ShapeConfigHanlder<TTarget> = { bivarianceHack(ctx: Context, shape: TTarget): void }['bivarianceHack'] export interface Shape extends NodeConfig { ... hitFunc: GetSet<ShapeConfigHanlder<this>, this>; sceneFunc: GetSet<ShapeConfigHanlder<this>, this>; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.