diff --git a/CHANGELOG.md b/CHANGELOG.md index e2ffa9f1c2a..818f64ef794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [next] +- chore(TS): Try to remove all TS-ERROR directives [#10309](https://github.com/fabricjs/fabric.js/pull/10309) - chore(): Make TS config more strict [#10308](https://github.com/fabricjs/fabric.js/pull/10308) - fix(Color): Support uppercase keywords [#10300](https://github.com/fabricjs/fabric.js/pull/10300) - fix(): The \_setLineDash method has additional side effects, altering the value of strokeDashArray [#10292](https://github.com/fabricjs/fabric.js/issues/10292) diff --git a/src/filters/BaseFilter.ts b/src/filters/BaseFilter.ts index 6305f31dca5..4d644ae702b 100644 --- a/src/filters/BaseFilter.ts +++ b/src/filters/BaseFilter.ts @@ -21,6 +21,7 @@ const regex = new RegExp(highPsourceCode, 'g'); export class BaseFilter< Name extends string, OwnProps extends Record = object, + SerializedProps extends Record = OwnProps, > { /** * Filter type @@ -383,19 +384,19 @@ export class BaseFilter< * stored in the static defaults property. * @return {Object} Object representation of an instance */ - toObject(): { type: Name } & OwnProps { + toObject(): { type: Name } & SerializedProps { const defaultKeys = Object.keys( (this.constructor as typeof BaseFilter).defaults || {}, - ) as (keyof OwnProps)[]; + ) as (keyof SerializedProps)[]; return { type: this.type, - ...defaultKeys.reduce((acc, key) => { + ...defaultKeys.reduce((acc, key) => { acc[key] = this[ key as keyof this ] as unknown as (typeof acc)[typeof key]; return acc; - }, {} as OwnProps), + }, {} as SerializedProps), }; } diff --git a/src/filters/ColorMatrix.ts b/src/filters/ColorMatrix.ts index 0d5b15c8207..fd4f38e85e5 100644 --- a/src/filters/ColorMatrix.ts +++ b/src/filters/ColorMatrix.ts @@ -7,7 +7,7 @@ import type { import { classRegistry } from '../ClassRegistry'; import { fragmentSource } from './shaders/colorMatrix'; -type ColorMatrixOwnProps = { +export type ColorMatrixOwnProps = { matrix: TMatColorMatrix; colorsOnly: boolean; }; @@ -36,7 +36,8 @@ export const colorMatrixDefaultValues: ColorMatrixOwnProps = { export class ColorMatrix< Name extends string = 'ColorMatrix', OwnProps extends object = ColorMatrixOwnProps, -> extends BaseFilter { + SerializedProps extends object = ColorMatrixOwnProps, +> extends BaseFilter { /** * Colormatrix for pixels. * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning @@ -81,18 +82,16 @@ export class ColorMatrix< const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; - if (colorsOnly) { - data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; - } else { + + data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; + data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; + data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; + if (!colorsOnly) { const a = data[i + 3]; - data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255; - data[i + 2] = - r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255; - data[i + 3] = - r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255; + data[i] += a * m[3]; + data[i + 1] += a * m[8]; + data[i + 2] += a * m[13]; + data[i + 3] += a * m[18]; } } } @@ -131,7 +130,7 @@ export class ColorMatrix< gl.uniform4fv(uniformLocations.uConstants, constants); } - toObject() { + toObject(): { type: Name } & SerializedProps { return { ...super.toObject(), matrix: [...this.matrix] as TMatColorMatrix, diff --git a/src/filters/ColorMatrixFilters.ts b/src/filters/ColorMatrixFilters.ts index 438360617f5..188f15e2550 100644 --- a/src/filters/ColorMatrixFilters.ts +++ b/src/filters/ColorMatrixFilters.ts @@ -7,7 +7,11 @@ type FixedFiltersOwnProps = { }; export function createColorMatrixFilter(key: string, matrix: TMatColorMatrix) { - const newClass = class extends ColorMatrix { + const newClass = class extends ColorMatrix< + typeof key, + FixedFiltersOwnProps, + FixedFiltersOwnProps + > { static type = key; static defaults = { @@ -15,7 +19,6 @@ export function createColorMatrixFilter(key: string, matrix: TMatColorMatrix) { matrix, }; - //@ts-expect-error TS wants matrix to be exported. toObject(): { type: string } & FixedFiltersOwnProps { return { type: this.type, colorsOnly: this.colorsOnly }; } diff --git a/src/filters/Composed.ts b/src/filters/Composed.ts index b5d3eeaf1a9..d4c094e731d 100644 --- a/src/filters/Composed.ts +++ b/src/filters/Composed.ts @@ -4,13 +4,21 @@ import { isWebGLPipelineState } from './utils'; import { classRegistry } from '../ClassRegistry'; type ComposedOwnProps = { - subFilters: BaseFilter[]; + subFilters: BaseFilter[]; +}; + +type ComposedSerializedProps = { + subFilters: Record[]; }; /** * A container class that knows how to apply a sequence of filters to an input image. */ -export class Composed extends BaseFilter<'Composed', ComposedOwnProps> { +export class Composed extends BaseFilter< + 'Composed', + ComposedOwnProps, + ComposedSerializedProps +> { /** * A non sparse array of filters to apply */ @@ -47,11 +55,7 @@ export class Composed extends BaseFilter<'Composed', ComposedOwnProps> { * Serialize this filter into JSON. * @returns {Object} A JSON representation of this filter. */ - //@ts-expect-error TS doesn't like this toObject - toObject(): { - type: 'Composed'; - subFilters: ReturnType['toObject']>[]; - } { + toObject() { return { type: this.type, subFilters: this.subFilters.map((filter) => filter.toObject()), diff --git a/src/filters/HueRotation.ts b/src/filters/HueRotation.ts index 4d631673f38..1cf2d0bec62 100644 --- a/src/filters/HueRotation.ts +++ b/src/filters/HueRotation.ts @@ -1,14 +1,23 @@ import { cos } from '../util/misc/cos'; import { sin } from '../util/misc/sin'; -import { ColorMatrix } from './ColorMatrix'; +import { + ColorMatrix, + type ColorMatrixOwnProps, + colorMatrixDefaultValues, +} from './ColorMatrix'; import type { TWebGLPipelineState, T2DPipelineState } from './typedefs'; import { classRegistry } from '../ClassRegistry'; -export type HueRotationOwnProps = { +export type HueRotationOwnProps = ColorMatrixOwnProps & { + rotation: number; +}; + +export type HueRotationSerializedProps = { rotation: number; }; export const hueRotationDefaultValues: HueRotationOwnProps = { + ...colorMatrixDefaultValues, rotation: 0, }; @@ -23,7 +32,8 @@ export const hueRotationDefaultValues: HueRotationOwnProps = { */ export class HueRotation extends ColorMatrix< 'HueRotation', - HueRotationOwnProps + HueRotationOwnProps, + HueRotationSerializedProps > { /** * HueRotation value, from -1 to 1. @@ -41,16 +51,28 @@ export class HueRotation extends ColorMatrix< aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sine, OneMinusCos = 1 - cosine; - this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]; - this.matrix[0] = cosine + OneMinusCos / 3; - this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[6] = cosine + aThird * OneMinusCos; - this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[12] = cosine + aThird * OneMinusCos; + this.matrix = [ + cosine + OneMinusCos / 3, + aThird * OneMinusCos - aThirdSqtSin, + aThird * OneMinusCos + aThirdSqtSin, + 0, + 0, + aThird * OneMinusCos + aThirdSqtSin, + cosine + aThird * OneMinusCos, + aThird * OneMinusCos - aThirdSqtSin, + 0, + 0, + aThird * OneMinusCos - aThirdSqtSin, + aThird * OneMinusCos + aThirdSqtSin, + cosine + aThird * OneMinusCos, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + ]; } isNeutralState() { @@ -62,8 +84,7 @@ export class HueRotation extends ColorMatrix< super.applyTo(options); } - //@ts-expect-error TS and classes with different methods - toObject(): { type: 'HueRotation'; rotation: number } { + toObject() { return { type: this.type, rotation: this.rotation, diff --git a/src/filters/WebGLFilterBackend.ts b/src/filters/WebGLFilterBackend.ts index aaa575712da..7cb3212ee8b 100644 --- a/src/filters/WebGLFilterBackend.ts +++ b/src/filters/WebGLFilterBackend.ts @@ -123,13 +123,11 @@ export class WebGLFilterBackend { const pipelineState: TWebGLPipelineState = { originalWidth: (source as HTMLImageElement).width || - // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state? - (source as HTMLImageElement).originalWidth || + (source as HTMLImageElement).naturalWidth || 0, originalHeight: (source as HTMLImageElement).height || - // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state? - (source as HTMLImageElement).originalHeight || + (source as HTMLImageElement).naturalHeight || 0, sourceWidth: width, sourceHeight: height, diff --git a/src/shapes/IText/ITextClickBehavior.ts b/src/shapes/IText/ITextClickBehavior.ts index 790f698a3de..224e90c32b3 100644 --- a/src/shapes/IText/ITextClickBehavior.ts +++ b/src/shapes/IText/ITextClickBehavior.ts @@ -8,7 +8,7 @@ import type { ITextEvents } from './ITextBehavior'; import { ITextKeyBehavior } from './ITextKeyBehavior'; import type { TOptions } from '../../typedefs'; import type { TextProps, SerializedTextProps } from '../Text/Text'; - +import type { IText } from './IText'; /** * `LEFT_CLICK === 0` */ @@ -42,8 +42,9 @@ export abstract class ITextClickBehavior< this.__lastPointer = {}; this.on('mousedown', this.onMouseDown); - // @ts-expect-error in reality it is an IText instance - this.draggableTextDelegate = new DraggableTextDelegate(this); + this.draggableTextDelegate = new DraggableTextDelegate( + this as unknown as IText, + ); super.initBehavior(); } diff --git a/src/shapes/IText/ITextKeyBehavior.ts b/src/shapes/IText/ITextKeyBehavior.ts index 4c2ed01dd79..054250d7442 100644 --- a/src/shapes/IText/ITextKeyBehavior.ts +++ b/src/shapes/IText/ITextKeyBehavior.ts @@ -118,11 +118,15 @@ export abstract class ITextKeyBehavior< } const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap; if (e.keyCode in keyMap) { - // @ts-expect-error legacy method calling pattern - this[keyMap[e.keyCode]](e); + (this[keyMap[e.keyCode] as keyof this] as (arg: KeyboardEvent) => void)( + e, + ); } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) { - // @ts-expect-error legacy method calling pattern - this[this.ctrlKeysMapDown[e.keyCode]](e); + ( + this[this.ctrlKeysMapDown[e.keyCode] as keyof this] as ( + arg: KeyboardEvent, + ) => void + )(e); } else { return; } @@ -150,8 +154,11 @@ export abstract class ITextKeyBehavior< return; } if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) { - // @ts-expect-error legacy method calling pattern - this[this.ctrlKeysMapUp[e.keyCode]](e); + ( + this[this.ctrlKeysMapUp[e.keyCode] as keyof this] as ( + arg: KeyboardEvent, + ) => void + )(e); } else { return; } diff --git a/src/shapes/Text/StyledText.ts b/src/shapes/Text/StyledText.ts index ac1ec2b49f0..5ad588dc1ff 100644 --- a/src/shapes/Text/StyledText.ts +++ b/src/shapes/Text/StyledText.ts @@ -97,8 +97,6 @@ export abstract class StyledText< * has no other properties, then it is also deleted. Finally, * if the line containing that character has no other characters * then it also is deleted. - * - * @param {string} property The property to compare between characters and text. */ cleanStyle(property: keyof TextStyleDeclaration) { if (!this.styles) { @@ -149,8 +147,7 @@ export abstract class StyledText< graphemeCount += this._textLines[i].length; } if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) { - // @ts-expect-error conspiracy theory of TS - this[property as keyof this] = stylePropertyValue; + this[property as keyof this] = stylePropertyValue as any; this.removeStyle(property); } } @@ -281,8 +278,11 @@ export abstract class StyledText< charIndex: number, ): CompleteTextStyleDeclaration { return { - // @ts-expect-error readonly - ...pick(this, (this.constructor as typeof StyledText)._styleProperties), + ...pick( + this, + (this.constructor as typeof StyledText) + ._styleProperties as (keyof this)[], + ), ...this._getStyleDeclaration(lineIndex, charIndex), } as CompleteTextStyleDeclaration; }