Skip to content

Refactor Color types for BC with @types/color#278

Open
mindplay-dk wants to merge 1 commit intoQix-:masterfrom
mindplay-dk:patch-1
Open

Refactor Color types for BC with @types/color#278
mindplay-dk wants to merge 1 commit intoQix-:masterfrom
mindplay-dk:patch-1

Conversation

@mindplay-dk
Copy link

The built-in types that came with v5 contained an annoying breaking change vs @types/color, in which a new, separate type ColorInstance needs to be imported separately, and Color itself is not a type and can't be use in type-hints anymore.

To illustrate the problem that was introduced:

image

It is conventional for constructors and instance types to be self-contained, as they are with native class declarations.

With this change in place:

image

To avoid a breaking change vs v5 types, this PR retains the newly introduced ColorInstance as an alias for Color.

@LitoMore
Copy link
Collaborator

LitoMore commented Jan 8, 2026

That's different. Our exported Color is just a function that returns a Color instance; you should not treat it as an instance type.

@mindplay-dk
Copy link
Author

Your exported Color is a constructor, and a function, and a namespace for factory functions like Color.rgb etc.

As explained, it is conventional in TS for constructors and types to use the same name - for class, it's built-into the language:

class Color {
    constructor(private value: string) {}
}

function setColor(color: Color) {
    // ...
}

setColor(new Color("#fff"))

The class keyword in TS generates a constructor and a type.

Having new Color return a type that's not Color when instanceof Color would say it is, is very unconventional.

The community-provided third-party types followed this TS convention.

I realize it is just a function in normal use, but you named it Color, following the class-name convention - and you have code in place to make sure it behaves like a class with instanceof at run-time:

color/index.js

Lines 23 to 25 in 4fda9a3

if (!(this instanceof Color)) {
return new Color(object, model);
}

Type names and variable names do not occupy the same namespace in TS - the Color variable and Color types exist in two different realms, and TS syntax is designed so that var and type names don't collide.

Importing typeof Color and getting any is very confusing.

Please reconsider. 🙂🙏

The built-in types that came with v5 contained an annoying breaking change vs `@types/color`, in which a new, separate type `ColorInstance` needs to be imported separately, and `Color` itself is not a type and can't be use in type-hints anymore. It is conventional for constructors and instance types to be self-contained, as they are with native `class` declarations.
@mindplay-dk
Copy link
Author

I've amended my PR to better comply with the linter rules, updated the tests for the types and added a test to demonstrate backwards compatibility with ColorInstance type-hints.

@Qix- can you approve this PR to run please?

@mindplay-dk
Copy link
Author

@Qix- hello? :-)

@mindplay-dk
Copy link
Author

To others looking for a workaround until this gets fixed:

  • copy the corrected color.d.ts to the root of your project.
  • in tsconfig.json add this to compilerOptions: "paths": { "color": ["./color.d.ts"] }

This will override the built-in types.

You can add the missing oklch methods as well, if needed - just copy and rename the lch methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments