diff --git a/src/Canvas.ts b/src/Canvas.ts index ef1784376..62d766418 100644 --- a/src/Canvas.ts +++ b/src/Canvas.ts @@ -136,7 +136,7 @@ export class Canvas { } catch (e) { try { return this._canvas.toDataURL(); - } catch (err) { + } catch (err: any) { Util.error( 'Unable to get data URL. ' + err.message + diff --git a/src/Container.ts b/src/Container.ts index 447e6c980..a6bfb1f0c 100644 --- a/src/Container.ts +++ b/src/Container.ts @@ -226,16 +226,16 @@ export abstract class Container< var result = this._generalFind(selector, true); return result.length > 0 ? result[0] : undefined; } - _generalFind( + _generalFind( selector: string | Function, findOne: boolean ) { var retArr: Array = []; - this._descendants((node: ChildNode) => { + this._descendants((node) => { const valid = node._isMatch(selector); if (valid) { - retArr.push(node); + retArr.push(node as unknown as ChildNode); } if (valid && findOne) { return true; @@ -256,7 +256,7 @@ export abstract class Container< if (!child.hasChildren()) { continue; } - shouldStop = (child as any)._descendants(fn); + shouldStop = (child as unknown as Container)._descendants(fn); if (shouldStop) { return true; } @@ -527,10 +527,7 @@ export abstract class Container< // there was "this" instead of "Container", // but it breaks react-konva types: https://github.com/konvajs/react-konva/issues/390 clipFunc: GetSet< - ( - ctx: CanvasRenderingContext2D, - shape: Container - ) => ClipFuncOutput, + (ctx: CanvasRenderingContext2D, shape: Container) => ClipFuncOutput, this >; } diff --git a/src/Context.ts b/src/Context.ts index ab4d14a27..d31ed3600 100644 --- a/src/Context.ts +++ b/src/Context.ts @@ -367,7 +367,7 @@ export class Context { clip(fillRule?: CanvasFillRule): void; clip(path: Path2D, fillRule?: CanvasFillRule): void; clip(...args: any[]) { - this._context.clip.apply(this._context, args); + this._context.clip.apply(this._context, args as any); } /** * closePath function. @@ -509,7 +509,7 @@ export class Context { fill(path: Path2D, fillRule?: CanvasFillRule): void; fill(...args: any[]) { // this._context.fill(); - this._context.fill.apply(this._context, args); + this._context.fill.apply(this._context, args as any); } /** * fillRect function. @@ -736,7 +736,7 @@ export class Context { // attrs that.setAttr = function () { - origSetter.apply(that, arguments); + origSetter.apply(that, arguments as any); var prop = arguments[0]; var val = arguments[1]; if ( diff --git a/src/Factory.ts b/src/Factory.ts index 2c252bd57..e50029579 100644 --- a/src/Factory.ts +++ b/src/Factory.ts @@ -1,3 +1,4 @@ +import { Node } from './Node'; import { Util } from './Util'; import { getComponentValidator } from './Validators'; @@ -15,7 +16,7 @@ export const Factory = { constructor.prototype[method] = constructor.prototype[method] || - function () { + function (this: Node) { var val = this.attrs[attr]; return val === undefined ? def : val; }; @@ -147,7 +148,7 @@ export const Factory = { var oldGetter = GET + Util._capitalize(oldMethodName); var oldSetter = SET + Util._capitalize(oldMethodName); - function deprecated() { + function deprecated(this: Node) { method.apply(this, arguments); Util.error( '"' + @@ -163,7 +164,7 @@ export const Factory = { constructor.prototype[oldSetter] = deprecated; }); }, - afterSetFilter() { + afterSetFilter(this: Node) { this._filterUpToDate = false; }, }; diff --git a/src/Node.ts b/src/Node.ts index e4d26eb4c..c7048e6f3 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -145,7 +145,7 @@ export abstract class Node { attrs: any = {}; index = 0; _allEventListeners: null | Array = null; - parent: Container | null = null; + parent: Container | null = null; _cache: Map = new Map(); _attachedDepsListeners: Map = new Map(); _lastPos: Vector2d | null = null; @@ -486,7 +486,7 @@ export abstract class Node { skipTransform?: boolean; skipShadow?: boolean; skipStroke?: boolean; - relativeTo?: Container; + relativeTo?: Container; }): { x: number; y: number; width: number; height: number } { // abstract method // redefine in Container and Shape @@ -607,7 +607,7 @@ export abstract class Node { filter.call(this, imageData); filterContext.putImageData(imageData, 0, 0); } - } catch (e) { + } catch (e: any) { Util.error( 'Unable to apply filter. ' + e.message + @@ -690,7 +690,7 @@ export abstract class Node { this._cache && this._cache.delete(ALL_LISTENERS); if (arguments.length === 3) { - return this._delegate.apply(this, arguments); + return this._delegate.apply(this, arguments as any); } var events = (evtStr as string).split(SPACE), len = events.length, @@ -810,7 +810,7 @@ export abstract class Node { for (var i = 0; i < targets.length; i++) { evt = Util.cloneObject(evt); evt.currentTarget = targets[i]; - handler.call(targets[i], evt); + handler.call(targets[i], evt as any); } }); } @@ -2584,6 +2584,7 @@ export abstract class Node { return Util.haveIntersection(screenRect, this.getClientRect()); } + // @ts-ignore: preventDefault: GetSet; // from filters @@ -2605,7 +2606,10 @@ export abstract class Node { threshold: GetSet; value: GetSet; - dragBoundFunc: GetSet<(this: Node, pos: Vector2d) => Vector2d, this>; + dragBoundFunc: GetSet< + (this: Node, pos: Vector2d, event: any) => Vector2d, + this + >; draggable: GetSet; dragDistance: GetSet; embossBlend: GetSet; @@ -3161,7 +3165,7 @@ addGetterSetter(Node, 'listening', true, getBooleanValidator()); addGetterSetter(Node, 'preventDefault', true, getBooleanValidator()); -addGetterSetter(Node, 'filters', null, function (val) { +addGetterSetter(Node, 'filters', null, function (this: Node, val) { this._filterUpToDate = false; return val; }); diff --git a/src/Shape.ts b/src/Shape.ts index fd6b0d27e..607a5b9b8 100644 --- a/src/Shape.ts +++ b/src/Shape.ts @@ -117,7 +117,7 @@ export const shapes: { [key: string]: Shape } = {}; // the approach is good. But what if we want to cache the shape before we add it into the stage // what color to use for hit test? -function _fillFunc(context) { +function _fillFunc(this: Node, context) { const fillRule = this.attrs.fillRule; if (fillRule) { context.fill(fillRule); @@ -135,23 +135,23 @@ function _strokeFuncHit(context) { context.stroke(); } -function _clearHasShadowCache() { +function _clearHasShadowCache(this: Node) { this._clearCache(HAS_SHADOW); } -function _clearGetShadowRGBACache() { +function _clearGetShadowRGBACache(this: Node) { this._clearCache(SHADOW_RGBA); } -function _clearFillPatternCache() { +function _clearFillPatternCache(this: Node) { this._clearCache(patternImage); } -function _clearLinearGradientCache() { +function _clearLinearGradientCache(this: Node) { this._clearCache(linearGradient); } -function _clearRadialGradientCache() { +function _clearRadialGradientCache(this: Node) { this._clearCache(radialGradient); } @@ -750,7 +750,7 @@ export class Shape< } } hitContext.putImageData(hitImageData, 0, 0); - } catch (e) { + } catch (e: any) { Util.error( 'Unable to draw hit graph from cached scene canvas. ' + e.message ); diff --git a/src/Stage.ts b/src/Stage.ts index a1bbb7cf6..4740d796e 100644 --- a/src/Stage.ts +++ b/src/Stage.ts @@ -264,7 +264,7 @@ export class Stage extends Container { } obj.container = typeof document !== 'undefined' && document.createElement('div'); - return Container.prototype.clone.call(this, obj); + return Container.prototype.clone.call(this, obj) as this; } destroy() { diff --git a/src/Util.ts b/src/Util.ts index 5cbcc281f..60b54f889 100644 --- a/src/Util.ts +++ b/src/Util.ts @@ -577,7 +577,7 @@ export const Util = { var rgb; // color string if (color in COLORS) { - rgb = COLORS[color]; + rgb = COLORS[color as keyof typeof COLORS]; return { r: rgb[0], g: rgb[1], @@ -588,7 +588,7 @@ export const Util = { return this._hexToRgb(color.substring(1)); } else if (color.substr(0, 4) === RGB_PAREN) { // rgb string - rgb = RGB_REGEX.exec(color.replace(/ /g, '')); + rgb = RGB_REGEX.exec(color.replace(/ /g, '')) as RegExpExecArray; return { r: parseInt(rgb[1], 10), g: parseInt(rgb[2], 10), @@ -620,7 +620,7 @@ export const Util = { }, // Parse named css color. Like "green" _namedColorToRBA(str: string) { - var c = COLORS[str.toLowerCase()]; + var c = COLORS[str.toLowerCase() as keyof typeof COLORS]; if (!c) { return null; } @@ -794,7 +794,7 @@ export const Util = { if (this._isPlainObject(obj[key])) { retObj[key] = this.cloneObject(obj[key]); } else if (this._isArray(obj[key])) { - retObj[key] = this.cloneArray(obj[key]); + retObj[key] = this.cloneArray(obj[key] as Array); } else { retObj[key] = obj[key]; } @@ -822,7 +822,7 @@ export const Util = { ); return Util.radToDeg(rad); }, - _getRotation(radians) { + _getRotation(radians: number) { return Konva.angleDeg ? Util.radToDeg(radians) : radians; }, _capitalize(str: string) { @@ -840,12 +840,12 @@ export const Util = { } console.warn(KONVA_WARNING + str); }, - each(obj, func) { + each(obj: Object, func: Function) { for (var key in obj) { - func(key, obj[key]); + func(key, obj[key as keyof typeof obj]); } }, - _inRange(val, left, right) { + _inRange(val: number, left: number, right: number) { return left <= val && val < right; }, _getProjectionToSegment(x1, y1, x2, y2, x3, y3) { @@ -876,7 +876,7 @@ export const Util = { }, // line as array of points. // line might be closed - _getProjectionToLine(pt: Vector2d, line, isClosed) { + _getProjectionToLine(pt: Vector2d, line: Array, isClosed: boolean) { var pc = Util.cloneObject(pt); var dist = Number.MAX_VALUE; line.forEach(function (p1, i) { diff --git a/src/filters/Blur.ts b/src/filters/Blur.ts index ef29f4e42..4cd12556e 100644 --- a/src/filters/Blur.ts +++ b/src/filters/Blur.ts @@ -46,7 +46,7 @@ import { getNumberValidator } from '../Validators'; OTHER DEALINGS IN THE SOFTWARE. */ -function BlurStack() { +function BlurStack(this: any) { this.r = 0; this.g = 0; this.b = 0; diff --git a/src/filters/RGB.ts b/src/filters/RGB.ts index 6af6568cc..3886f3ae7 100644 --- a/src/filters/RGB.ts +++ b/src/filters/RGB.ts @@ -35,7 +35,7 @@ export const RGB: Filter = function (imageData) { } }; -Factory.addGetterSetter(Node, 'red', 0, function (val) { +Factory.addGetterSetter(Node, 'red', 0, function (this: Node, val) { this._filterUpToDate = false; if (val > 255) { return 255; @@ -54,7 +54,7 @@ Factory.addGetterSetter(Node, 'red', 0, function (val) { * @returns {Integer} */ -Factory.addGetterSetter(Node, 'green', 0, function (val) { +Factory.addGetterSetter(Node, 'green', 0, function (this: Node, val) { this._filterUpToDate = false; if (val > 255) { return 255; diff --git a/src/filters/RGBA.ts b/src/filters/RGBA.ts index 5fe107295..793128c63 100644 --- a/src/filters/RGBA.ts +++ b/src/filters/RGBA.ts @@ -36,7 +36,7 @@ export const RGBA: Filter = function (imageData) { } }; -Factory.addGetterSetter(Node, 'red', 0, function (val) { +Factory.addGetterSetter(Node, 'red', 0, function (this: Node, val: number) { this._filterUpToDate = false; if (val > 255) { return 255; @@ -55,7 +55,7 @@ Factory.addGetterSetter(Node, 'red', 0, function (val) { * @returns {Integer} */ -Factory.addGetterSetter(Node, 'green', 0, function (val) { +Factory.addGetterSetter(Node, 'green', 0, function (this: Node, val) { this._filterUpToDate = false; if (val > 255) { return 255; @@ -84,7 +84,7 @@ Factory.addGetterSetter(Node, 'blue', 0, RGBComponent, Factory.afterSetFilter); * @returns {Integer} */ -Factory.addGetterSetter(Node, 'alpha', 1, function (val) { +Factory.addGetterSetter(Node, 'alpha', 1, function (this: Node, val) { this._filterUpToDate = false; if (val > 1) { return 1; diff --git a/src/shapes/Text.ts b/src/shapes/Text.ts index a7820c421..d65ede8ac 100644 --- a/src/shapes/Text.ts +++ b/src/shapes/Text.ts @@ -104,10 +104,10 @@ function getDummyContext() { return dummyContext; } -function _fillFunc(context: Context) { +function _fillFunc(this: Text, context: Context) { context.fillText(this._partialText, this._partialTextX, this._partialTextY); } -function _strokeFunc(context: Context) { +function _strokeFunc(this: Text, context: Context) { context.setAttr('miterLimit', 2); context.strokeText(this._partialText, this._partialTextX, this._partialTextY); } diff --git a/src/shapes/TextPath.ts b/src/shapes/TextPath.ts index 150f8f8c0..f329ef3a2 100644 --- a/src/shapes/TextPath.ts +++ b/src/shapes/TextPath.ts @@ -21,10 +21,10 @@ export interface TextPathConfig extends ShapeConfig { var EMPTY_STRING = '', NORMAL = 'normal'; -function _fillFunc(context) { +function _fillFunc(this: TextPath, context) { context.fillText(this.partialText, 0, 0); } -function _strokeFunc(context) { +function _strokeFunc(this: TextPath, context) { context.strokeText(this.partialText, 0, 0); } diff --git a/src/shapes/Transformer.ts b/src/shapes/Transformer.ts index 97a61c9a8..cb51c97dc 100644 --- a/src/shapes/Transformer.ts +++ b/src/shapes/Transformer.ts @@ -551,11 +551,9 @@ export class Transformer extends Group { _createElements() { this._createBack(); - ANCHORS_NAMES.forEach( - function (name) { - this._createAnchor(name); - }.bind(this) - ); + ANCHORS_NAMES.forEach((name) => { + this._createAnchor(name); + }); this._createAnchor('rotater'); } @@ -605,25 +603,25 @@ export class Transformer extends Group { width: 0, height: 0, draggable: true, - sceneFunc(ctx) { - var tr = this.getParent(); + sceneFunc(ctx, shape) { + var tr = shape.getParent() as Transformer; var padding = tr.padding(); ctx.beginPath(); ctx.rect( -padding, -padding, - this.width() + padding * 2, - this.height() + padding * 2 + shape.width() + padding * 2, + shape.height() + padding * 2 ); - ctx.moveTo(this.width() / 2, -padding); + ctx.moveTo(shape.width() / 2, -padding); if (tr.rotateEnabled()) { ctx.lineTo( - this.width() / 2, - -tr.rotateAnchorOffset() * Util._sign(this.height()) - padding + shape.width() / 2, + -tr.rotateAnchorOffset() * Util._sign(shape.height()) - padding ); } - ctx.fillStrokeShape(this); + ctx.fillStrokeShape(shape); }, hitFunc: (ctx, shape) => { if (!this.shouldOverdrawWholeArea()) { diff --git a/test/sandbox.html b/test/sandbox.html index a46d40666..4b19f3695 100644 --- a/test/sandbox.html +++ b/test/sandbox.html @@ -46,6 +46,7 @@ fill: 'red', draggable: true, }); + layer.add(circle); const tr = new Konva.Transformer({ diff --git a/tsconfig.json b/tsconfig.json index 83ad40e03..a9c5df04c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,14 @@ "moduleResolution": "node", "declaration": true, "removeComments": false, - "strictNullChecks": true, + + "strict": true, + "noImplicitAny": false, + "noImplicitThis": false, + "useUnknownInCatchVariables": false, + // probably we would never enable this one + // because it's too strict, konva generates many functions on the runtime + "strictPropertyInitialization": false, }, "include": ["./src/**/*.ts"] }