打字稿类型a不可分配给类型b

时间:2019-05-08 08:47:46

标签: typescript konvajs

故事

我将konva library与Typescript一起使用,Typescript是HTML5 Canvas JavaScript框架。

这是一个简单的教程代码,我从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);

但是我的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)

ShapeShape.d.ts中,而RectRect.d.ts中。 而且我看到Rect扩展了Shape!但是VSC显示错误。

如果我将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
    ...
    ...

问题

我知道layer.add()函数仅接受Shape类型。但是,您知道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

我无法理解为什么layer.add()即使扩展了Rect类型也不能接受Shape类型。我想念什么?

我需要你的建议。 谢谢。

1 个答案:

答案 0 :(得分:2)

不幸的是,显然没有使用strictFunctionTypes测试库的定义。

如果未激活此选项,则函数为双变量关系,但在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 下,函数与参数类型相反。这意味着:

hitFunc

您遇到的错误是在sceneFunc上(如果已在this上修复),这些函数采用第二个参数Shape<ShapeConfig>,实际上是hitFunc 。当我们尝试在Rect中分配具有第二个参数的this中分配Rect时,也会触发错误,该参数也键入为layer.add(box as unknown as Shape<ShapeConfig>); 但实际上是strictFunctionTypes。您不能将具有派生参数类型的函数分配给可以接受任何基本类型参​​数的函数签名。

有多种可能的解决方案:

  1. 使用类型断言

    strictFunctionTypes: false
  2. 禁用hitFunc(tsconfig中的sceneFunc消失了)

  3. 提交一个拉动请求以明确键入,以使strictFunctionTypes: trueexport 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>; } import pandas df = pandas.DataFrame({ "date" : ["day_1","day_1","day_2","day_3","day_4"], "block" : ["1", "2", "1", "1", "1"], "start_time" : ["08:00","11:00","08:00","09:00", "09:00"], "end_time" :["10:00","15:00","10:00","11:00", "13:00"] }) 下按照here的行为发生双变量事件。在这种情况下,它将起作用并保留功能:

     [
     {
      "day_1":[
         {
            "1":{
               "start_time":"08:00:00",
               "end_time":"10:00:00"
            },
            "2":{
               "start_time":"11:00:00",
               "end_time":"15:00:00"
            }
         }
      ],
      "day_2":{
         "1":{
            "start_time":"2019-04-29 08:00:00",
            "end_time":"2019-04-29 10:00:00"
         }
      }
     }
     ]