Pesquisa de site

javascript - Preciso de um exemplo de como usar fabricjs.d.ts com TypeScript


Eu uso fabricjs em um projeto que estou tentando converter para usar TypeScript, mas não consigo descobrir como usá-lo. Anteriormente, eu criava meus próprios objetos personalizados fazendo o seguinte:

my.namespace.Control = fabric.util.createClass(fabric.Object, {
    id: "",
    type: 'Control',
    color: "#000000", 
    ...
});

No meu novo projeto, instalei o arquivo TypeDefinition daqui, mas não consigo descobrir como devo usá-lo?

Olhando o arquivo .d.ts, fabric.Object não parece ser uma Função, portanto não é permitido passá-lo para createClass, e createClass em si retorna void, então eu não posso atribuir o valor a uma variável.

Mesmo que tudo isso funcione, como devo formatar isso para que funcione do jeito TypeScript? Ou seja, o que devo exportar para poder importar em outro lugar onde a classe Control é necessária?

Alguém realmente tem algum exemplo de como fazer isso?

Resposta #1

Você pode simplesmente definir uma classe TypeScript que estenda uma classe Fabric.

export interface IMindObjectOptions {
    item: IMindItem;
}

export interface IMindExpanderOptions  extends IMindObjectOptions {
    x: number;
    y: number;
    radius: number;
    isExpanded: boolean;
}

export class MindExpander extends fabric.Circle implements IMindObjectOptions {

    public constructor(options: IMindExpanderOptions) {
        const circleOptions: ICircleOptions = {
            originX: "center",
            originY: "center",
            left: options.x,
            top: options.y,
            radius: options.radius,
            stroke: "#000000",
            fill: options.isExpanded ? "#00FFFF": "#00FF00",
            selectable: false
        };
        super(circleOptions);
        this.item = options.item;
    }

    public readonly item: IMindItem;
}

!!! O código acima funciona bem no navegador, mas não no ambiente Node.js.

Para trabalhar em um ambiente Node.js, como executar testes unitários sem um navegador, você precisa:

import {assert} from "chai";
import * as f from 'fabric';
import {ITextOptions} from "fabric";

declare function require(s: string): any;
declare const __dirname: string;

const fabric = require("fabric").fabric;

interface ITextConstructor {
    new(text: string, options: ITextOptions): f.Text;
}
function getTextConstructor(): ITextConstructor {
    return fabric.Text;
}

describe("nodejs setup", function () {
    it("fabric is imported correctly", function () {
        const x = fabric.Text as f.Text;
        assert.equal(typeof x, "function");
    });
    it("fabric class is extensible", function () {
        class SubText extends getTextConstructor() {
            public constructor(text: string, options: fabric.ITextOptions) {
                super(text, options);
            }
        }

        const c = new SubText("Hello", {left: 100, top: 100});
        assert.equal(c.text, "Hello");
        assert.isNotNull(c);
    });
});

Resposta #2

A maneira antiga de usar seu fabricjs.d.ts é no topo do seu arquivo:

/// <reference path="path/to/your/fabricjs.d.ts" />

Se você obtê-lo com tsd, você precisa referenciar seu arquivo de pacote tsd.d.ts

Mas agora, com o TypeScript 1.6.2 e o VSCode, você só precisa baixar o arquivo de referência via tsd para obter as definições no seu código.

No arquivo d.ts você pode encontrar a assinatura de 2 métodos :

createClass(parent: Function, properties?: any): void;

createClass(properties?: any): void;

Então, seu código parece inválido porque fabric.Object como interface IObjectStatict não pode ser atribuível ao tipo Function. Você pode fazer um cast de fabric.Object como uma Function fazendo

my.namespace.Control = fabric.util.createClass(<Function>fabric.Object, {
  id: '',
  type: 'Control',
  color: '#000000', 
  ...
});

Artigos relacionados