Skip to content

Commit

Permalink
Audit function parameter and return types (3/2) (#461)
Browse files Browse the repository at this point in the history
* All Color methods return a Color object; use getColor on remaining fns

* add comments

* remove duplicate getColor call

* remove duplicates and add missing tests

* More consistent Color namespace type exports

* add comment
  • Loading branch information
jgerigmeyer authored Feb 29, 2024
1 parent ae9ea42 commit c258d1d
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 38 deletions.
4 changes: 1 addition & 3 deletions src/distance.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import ColorSpace from "./space.js";
import getColor from "./getColor.js";

/**
* Euclidean distance of colors in an arbitrary color space
*/
export default function distance (color1, color2, space = "lab") {
[color1, color2] = getColor([color1, color2]);

space = ColorSpace.get(space);

// Assume getColor() is called on color in space.from()
let coords1 = space.from(color1);
let coords2 = space.from(color2);

Expand Down
2 changes: 2 additions & 0 deletions src/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ export default function set (color, prop, value) {

return color;
}

set.returns = "color";
2 changes: 2 additions & 0 deletions src/setAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export default function setAll (color, space, coords) {
color.coords = space.to(color.space, coords);
return color;
}

setAll.returns = "color";
7 changes: 5 additions & 2 deletions src/space.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {type, parseCoordGrammar, serializeNumber, mapRange} from "./util.js";
import {getWhite} from "./adapt.js";
import hooks from "./hooks.js";
import getColor from "./getColor.js";

const ε = .000075;

Expand Down Expand Up @@ -173,7 +174,8 @@ export default class ColorSpace {

to (space, coords) {
if (arguments.length === 1) {
[space, coords] = [space.space, space.coords];
const color = getColor(space);
[space, coords] = [color.space, color.coords];
}

space = ColorSpace.get(space);
Expand Down Expand Up @@ -222,7 +224,8 @@ export default class ColorSpace {

from (space, coords) {
if (arguments.length === 1) {
[space, coords] = [space.space, space.coords];
const color = getColor(space);
[space, coords] = [color.space, color.coords];
}

space = ColorSpace.get(space);
Expand Down
65 changes: 39 additions & 26 deletions types/src/color.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ import ColorSpace, { Ref } from "./space.js";
import SpaceAccessors from "./space-coord-accessors.js";

import {
to,
to as toFn,
parse,
serialize,
inGamut,
toGamut,
distance,
equals,
inGamut as inGamutFn,
toGamut as toGamutFn,
distance as distanceFn,
equals as equalsFn,
get,
getAll,
set,
setAll,
getAll as getAllFn,
setAll as setAllFn,
display,
} from "./index-fn.js";

Expand Down Expand Up @@ -69,20 +68,34 @@ export type ToColorPrototype<T extends (...args: any[]) => any> = T extends (
: (...args: A) => R
: never;

/** Convert a function to a Color namespace property (returning a Color) */
export type ToColorNamespace<T extends (...args: any[]) => any> = T extends (
...args: infer A
) => infer R
? T extends { returns: "color" }
? (...args: A) => Color
: (...args: A) => R
: never;

declare namespace Color {
export {
getAll,
set,
setAll,
to,
equals,
inGamut,
toGamut,
distance,
serialize as toString,
};
// Functions defined using Color.defineFunctions
export const getAll: ToColorNamespace<typeof getAllFn>;
export const setAll: ToColorNamespace<typeof setAllFn>;
export const to: ToColorNamespace<typeof toFn>;
export const equals: ToColorNamespace<typeof equalsFn>;
export const inGamut: ToColorNamespace<typeof inGamutFn>;
export const toGamut: ToColorNamespace<typeof toGamutFn>;
export const distance: ToColorNamespace<typeof distanceFn>;
// `get` is defined below as a static method on the Class,
// and `toString` is intentionally not overridden for the namespace

export { util, hooks, WHITES, ColorSpace as Space, parse, defaults };
export const spaces: typeof ColorSpace["registry"];

// Must be manually defined due to overloads
// These should always match the signature of the original function
export function set (color: ColorTypes, prop: Ref, value: number | ((coord: number) => number)): Color;
export function set (color: ColorTypes, props: Record<string, number | ((coord: number) => number)>): Color;
}

declare class Color extends SpaceAccessors implements PlainColorObject {
Expand Down Expand Up @@ -129,13 +142,13 @@ declare class Color extends SpaceAccessors implements PlainColorObject {

// Functions defined using Color.defineFunctions
get: ToColorPrototype<typeof get>;
getAll: ToColorPrototype<typeof getAll>;
setAll: ToColorPrototype<typeof setAll>;
to: ToColorPrototype<typeof to>;
equals: ToColorPrototype<typeof equals>;
inGamut: ToColorPrototype<typeof inGamut>;
toGamut: ToColorPrototype<typeof toGamut>;
distance: ToColorPrototype<typeof distance>;
getAll: ToColorPrototype<typeof getAllFn>;
setAll: ToColorPrototype<typeof setAllFn>;
to: ToColorPrototype<typeof toFn>;
equals: ToColorPrototype<typeof equalsFn>;
inGamut: ToColorPrototype<typeof inGamutFn>;
toGamut: ToColorPrototype<typeof toGamutFn>;
distance: ToColorPrototype<typeof distanceFn>;
toString: ToColorPrototype<typeof serialize>;

// Must be manually defined due to overloads
Expand Down
10 changes: 8 additions & 2 deletions types/src/set.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { ColorTypes, PlainColorObject } from "./color.js";
import { Ref } from "./space.js";

export default function set (
declare namespace set {
let returns: "color";
}

declare function set (
color: ColorTypes,
prop: Ref,
value: number | ((coord: number) => number)
): PlainColorObject;
export default function set (
declare function set (
color: ColorTypes,
props: Record<string, number | ((coord: number) => number)>
): PlainColorObject;

export default set;
2 changes: 1 addition & 1 deletion types/src/setAll.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Color, { ColorTypes, PlainColorObject } from "./color.js";
import { ColorTypes, PlainColorObject } from "./color.js";
import ColorSpace from "./space.js";

declare namespace setAll {
Expand Down
6 changes: 3 additions & 3 deletions types/src/space.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { White } from "./adapt.js";
import Color, { ColorConstructor, ColorObject, Coords, PlainColorObject } from "./color.js";
import { ColorConstructor, Coords, ColorTypes } from "./color.js";

export interface Format {
/** @default "function" */
Expand Down Expand Up @@ -127,7 +127,7 @@ export default class ColorSpace {
white: White;
gamutSpace: ColorSpace;

from (color: {space: ColorSpace, coords: Coords, alpha?: number | undefined}): Coords;
from (color: ColorTypes): Coords;
from (space: string | ColorSpace, coords: Coords): Coords;

getFormat (format?: string | Format): Format | null;
Expand All @@ -136,7 +136,7 @@ export default class ColorSpace {

inGamut (coords: Coords, options?: { epsilon?: number }): boolean;

to (color: {space: ColorSpace, coords: Coords, alpha?: number | undefined}): Coords;
to (color: ColorTypes): Coords;
to (space: string | ColorSpace, coords: Coords): Coords;

toString (): string;
Expand Down
2 changes: 2 additions & 0 deletions types/test/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ set("red", {
});

new Color("red").set("foo", 123); // $ExpectType Color
Color.set("red", "foo", 123); // $ExpectType Color
Color.set(new Color("red"), "foo", 123); // $ExpectType Color
2 changes: 2 additions & 0 deletions types/test/setAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ setAll(

new Color("red").setAll("srgb", [1, 2, 3]); // $ExpectType Color
new Color("red").setAll(sRGB, [1, 2, 3]); // $ExpectType Color
Color.setAll("red", "srgb", [1, 2, 3]); // $ExpectType Color
Color.setAll(new Color("red"), "srgb", [1, 2, 3]); // $ExpectType Color
3 changes: 2 additions & 1 deletion types/test/spaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ ColorSpace.resolveCoord("p3.0", "p3");
ColorSpace.resolveCoord(["p3", "r"], "p3");

space.to(new Color("red")); // $ExpectType Coords
space.to("red"); // $ExpectType Coords
space.to({space: space, coords: [1, 2, 3], alpha: 1}); // $ExpectType Coords
space.to({space: space, coords: [1, 2, 3]}); // $ExpectType Coords
space.to(space, [1, 2, 3]); // $ExpectType Coords
space.to("srgb", [1, 2, 3]); // $ExpectType Coords

space.from(new Color("red")); // $ExpectType Coords
space.from("red"); // $ExpectType Coords
space.from({space: space, coords: [1, 2, 3], alpha: 1}); // $ExpectType Coords
space.from({space: space, coords: [1, 2, 3]}); // $ExpectType Coords
space.from(space, [1, 2, 3]); // $ExpectType Coords
space.from("srgb", [1, 2, 3]); // $ExpectType Coords

5 changes: 5 additions & 0 deletions types/test/to.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Color from "colorjs.io/src";
import to from "colorjs.io/src/to";

// @ts-expect-error
Expand All @@ -8,3 +9,7 @@ to("red");

to("red", "srgb"); // $ExpectType PlainColorObject
to("red", "srgb", { inGamut: false }); // $ExpectType PlainColorObject

new Color("red").to("srgb"); // $ExpectType Color
Color.to("red", "srgb"); // $ExpectType Color
Color.to(new Color("red"), "srgb"); // $ExpectType Color
2 changes: 2 additions & 0 deletions types/test/toGamut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ new Color("red").toGamut(); // $ExpectType Color
new Color("red").toGamut({ method: "clip", space: "srgb" }); // $ExpectType Color
new Color("red").toGamut({ method: "clip", space: sRGB }); // $ExpectType Color
new Color("red").toGamut("srgb"); // $ExpectType Color
Color.toGamut("red"); // $ExpectType Color
Color.toGamut(new Color("red")); // $ExpectType Color

0 comments on commit c258d1d

Please sign in to comment.