blockly: TypeScript definition problems

The current blockly.d.ts TypeScript definition file does not accurately describe the data types in many places of the API, either through errors in the JSDoc types, insufficiently rich typing, or just incompatibilities between Closure and TS.

I’m currently upgrading our codebase to use Blockly July 2019 release, from its npm package rather than directly from the repo, and the supplied TypeScript definitions, rather than our very outdated and hacked definitions.

I’m opening this issue to start documenting the areas in which I’ve had to patch up or workaround issues in the supplied blockly.d.ts file…

  • Mismatch between Blockly.Options and BlocklyOptions - the inject fn takes the former, but really should take the latter
  • A BlockSvg should have a workspace of type WorkspaceSvg
  • BlockSvg.render is missing
  • WorkspaceSvg.newBlock should return a BlockSvg
  • Events.Abstract should ideally have a type property, rather than individual subclasses having it
  • Icon is missing some internal props and methods, which makes adding a custom Icon a pain

I’ve managed to fix above with the following…

import Blockly from 'blockly'

declare module 'blockly' {

    interface BlockSvg {
        workspace: Blockly.WorkspaceSvg

        render(opt_bubble?: boolean): void
    }

    interface Options extends Blockly.BlocklyOptions {
    }

    interface WorkspaceSvg {
        newBlock(prototypeName: string, opt_id?: string): Blockly.BlockSvg
    }

    interface Icon {
        block_: Blockly.BlockSvg
        iconGroup_?: SVGElement

        drawIcon_(group: SVGElement): void

        setVisible(visible: boolean): void
    }

    namespace Events {
        interface Abstract {
            type: string
        }
    }
}
  • Blockly.Msg is declared as a module with a single LOGIC_HUE prop, preventing arbitrary overrides within TS code, really it should be declared as a Record<string, string> to allow any message key to be overridden. The only work-around I’ve found for this is use of // @ts-ignore 😦
  • Blockly.VariableMap.prototype.getVariable returns Blockly.VariableModel but should be Blockly.VariableModel | null according to the docs

more to come…

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (8 by maintainers)

Most upvoted comments

Adding more to this. The different renderers we publish are currently not included in the blockly.d.ts

Hey gang, finally getting round to another Blockly update, from 3.20200123.1 to 3.20200625.2, so I thought I should keep this ticket updated.

Here are my type fixes for this release…

import 'blockly'

declare module 'blockly' {

    interface BlocklyOptions {
        parentWorkspace?: Blockly.WorkspaceSvg
    }

    interface WorkspaceSvg {
        newBlock(prototypeName: string, opt_id?: string): Blockly.BlockSvg
    }

    interface Icon {
        iconGroup_?: SVGElement

        setVisible(visible: boolean): void
    }

    module fieldRegistry {
        function register(type: string, fieldClass: { fromJson: (options: any) => Blockly.Field }): void
    }

    namespace Events {
        interface Abstract {
            type: string
        }
    }
}

The most notable change being the Blockly.fieldRegistry.register fieldClass param appears to be declared incorrectly…

The blockly.d.ts declares register as:

function register(type: string, fieldClass: { (_0: any[]): any /*missing*/ }): void;

but fieldClass should be an object containing a fromJson function rather than just a function.