From aa68b388afb22a298a331af031f94e9467c88fc6 Mon Sep 17 00:00:00 2001 From: ppillot Date: Thu, 23 Nov 2023 23:00:11 -0500 Subject: [PATCH 1/3] Colormaker is a class: it can't be called without new Previous implementation of Colormaker was probably relying on JS prototypal inheritance. Colormaker cannot be called like a function anymore. (cherry picked from commit 08997338f69726056b5a9042d24a608ecc544ee7) --- src/color/colormaker-registry.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/color/colormaker-registry.ts b/src/color/colormaker-registry.ts index f5314d4b..6fcfa34e 100644 --- a/src/color/colormaker-registry.ts +++ b/src/color/colormaker-registry.ts @@ -201,15 +201,13 @@ class ColormakerRegistry { delete this.userSchemes[ id ] } - _createScheme (constructor: any) { - const _Colormaker = function (this: any, params: ColormakerParameters) { - Colormaker.call(this, params) - constructor.call(this, params) + _createScheme (constructor: any): typeof Colormaker { + class _Colormaker extends Colormaker { + constructor (params: ColormakerParameters) { + super(params) + constructor.call(this, params) + } } - - _Colormaker.prototype = Colormaker.prototype - _Colormaker.prototype.constructor = Colormaker - return _Colormaker } From 5e6cf7c96d9554936460814d66427b4bdae64055 Mon Sep 17 00:00:00 2001 From: ppillot Date: Sat, 23 Dec 2023 15:34:14 -0500 Subject: [PATCH 2/3] Typings: colormaker registry --- src/color/colormaker-registry.ts | 19 ++++++++++--------- src/color/colormaker.ts | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/color/colormaker-registry.ts b/src/color/colormaker-registry.ts index 6fcfa34e..5fce134c 100644 --- a/src/color/colormaker-registry.ts +++ b/src/color/colormaker-registry.ts @@ -5,7 +5,7 @@ */ import { generateUUID } from '../math/math-utils' -import Colormaker, { ColormakerParameters } from './colormaker' +import Colormaker, { ColormakerConstructor, ColormakerParameters } from './colormaker' import SelectionColormaker, { SelectionSchemeData } from './selection-colormaker' import Structure from '../structure/structure' @@ -75,8 +75,8 @@ const ColormakerModes = { * global {@link src/globals.js~ColormakerRegistry} instance. */ class ColormakerRegistry { - schemes: { [k: string]: any } - userSchemes: { [k: string]: any } + schemes: { [k: string]: ColormakerConstructor } + userSchemes: { [k: string]: ColormakerConstructor } constructor () { this.schemes = {} @@ -87,13 +87,14 @@ class ColormakerRegistry { const p = params || {} const id = (p.scheme || '').toLowerCase() - let SchemeClass + let SchemeClass: ColormakerConstructor if (id in this.schemes) { SchemeClass = this.schemes[ id ] } else if (id in this.userSchemes) { SchemeClass = this.userSchemes[ id ] } else { + //@ts-expect-error abstract class used as a constructor SchemeClass = Colormaker } @@ -106,7 +107,7 @@ class ColormakerRegistry { * @return {Object} available schemes */ getSchemes () { - const types: { [k: string]: any } = {} + const types: { [k: string]: string } = {} Object.keys(this.schemes).forEach(function (k) { types[ k ] = k @@ -138,7 +139,7 @@ class ColormakerRegistry { * @param {Colormaker} scheme - the colormaker * @return {undefined} */ - add (id: string, scheme: typeof Colormaker) { + add (id: string, scheme: ColormakerConstructor) { id = id.toLowerCase() this.schemes[ id ] = scheme } @@ -169,7 +170,7 @@ class ColormakerRegistry { * @param {String} label - scheme label * @return {String} id to refer to the registered scheme */ - addScheme (scheme: any, label?: string) { + addScheme (scheme: ColormakerConstructor, label?: string) { if (!(scheme instanceof Colormaker)) { scheme = this._createScheme(scheme) } @@ -183,7 +184,7 @@ class ColormakerRegistry { * @param {String} [label] - scheme label * @return {String} id to refer to the registered scheme */ - _addUserScheme (scheme: any, label?: string) { + _addUserScheme (scheme: ColormakerConstructor, label?: string) { label = label || '' const id = `${generateUUID()}|${label}`.toLowerCase() this.userSchemes[ id ] = scheme @@ -201,7 +202,7 @@ class ColormakerRegistry { delete this.userSchemes[ id ] } - _createScheme (constructor: any): typeof Colormaker { + _createScheme (constructor: any): ColormakerConstructor { class _Colormaker extends Colormaker { constructor (params: ColormakerParameters) { super(params) diff --git a/src/color/colormaker.ts b/src/color/colormaker.ts index 18335498..5866bd7a 100644 --- a/src/color/colormaker.ts +++ b/src/color/colormaker.ts @@ -61,6 +61,7 @@ export interface ColormakerParameters extends ScaleParameters { export type StuctureColormakerParams = { structure: Structure } & Partial export type VolumeColormakerParams = { volume: Volume } & Partial export type ColormakerScale = (v: number) => number +export type ColormakerConstructor = new (...p: ConstructorParameters) => Colormaker const tmpColor = new Color() From 9554f04c07fb8a8ef4ca722fa1559c093d17a92d Mon Sep 17 00:00:00 2001 From: ppillot Date: Mon, 8 Jan 2024 22:21:57 -0500 Subject: [PATCH 3/3] Fix addScheme() typings One type of argument was missing, as `scheme` can have 2 shapes (either a class derived from Colormaker or a function that redefines the Colormaker prototype on a derived class). It was necessary to add type predicates to correctly infer the type of `scheme` within the addScheme method. --- src/color/colormaker-registry.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/color/colormaker-registry.ts b/src/color/colormaker-registry.ts index 5fce134c..302dae9a 100644 --- a/src/color/colormaker-registry.ts +++ b/src/color/colormaker-registry.ts @@ -9,6 +9,8 @@ import Colormaker, { ColormakerConstructor, ColormakerParameters } from './color import SelectionColormaker, { SelectionSchemeData } from './selection-colormaker' import Structure from '../structure/structure' +type ColormakerDefinitionFunction = ((this: Colormaker, param?: ColormakerParameters) => void) + const ColormakerScales = { '': '', @@ -170,8 +172,8 @@ class ColormakerRegistry { * @param {String} label - scheme label * @return {String} id to refer to the registered scheme */ - addScheme (scheme: ColormakerConstructor, label?: string) { - if (!(scheme instanceof Colormaker)) { + addScheme (scheme: ColormakerConstructor|ColormakerDefinitionFunction, label?: string) { + if (!(isColormakerSubClass(scheme))) { scheme = this._createScheme(scheme) } @@ -202,7 +204,7 @@ class ColormakerRegistry { delete this.userSchemes[ id ] } - _createScheme (constructor: any): ColormakerConstructor { + _createScheme (constructor: ColormakerDefinitionFunction): ColormakerConstructor { class _Colormaker extends Colormaker { constructor (params: ColormakerParameters) { super(params) @@ -256,4 +258,10 @@ class ColormakerRegistry { } } +function isColormakerSubClass ( + scheme: ColormakerConstructor|((this: Colormaker, param?: ColormakerParameters) => void) +): scheme is ColormakerConstructor { + return (scheme instanceof Colormaker) +} + export default ColormakerRegistry