Pour faire suite à mon dernier article sur l'exhaustivité des types, et quelques messages divers, je vous propose de représenter une couleur.
Pour ça, on va utiliser une représentation hexadécimale, vous savez, comme en CSS avec #7FFF00
.
D'ailleurs, en synthèse additive, une couleur, ça se décompose généralement en 3 canaux :
type ColorCanal = typeof Red | typeof Green | typeof Blue;
Chaque canal représente une quantité de couleur :
- Red :
7F
; - Green :
FF
; - Blue :
00
.
La quantité va de 00
à FF
, c'est une base 16, il y a donc 16 × 16 possibilités par canal, soit 256 :
type HexaDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
type HexaCanalColor = `${HexaDigit}${HexaDigit}`;
On vient d'utiliser un Template Literal pour assembler deux
HexaDigit
et donc représenter les nombres de00
àFF
.
On pourrait se dire qu'avec ce Template Literal, on peut représenter la couleur sous forme hexadécimale via :
type HexaColor = `#${HexaCanalColor}${HexaCanalColor}${HexaCanalColor}`;
Cependant, nous sommes accueillis avec l'erreur : TS2590: Expression produces a union type that is too complex to represent.
. Cette erreur peut arriver lorsqu'il y a plus de 100 000 possibilités pour un Union Type.
Or ici, lorsqu'on déclare ce type, on essaie de représenter l'ensemble des couleurs possibles en RGB soit 256 × 256 × 256 couleurs : 16 777 216.
Je vous propose alors d'utiliser nos canaux et de faire :
type Color = Record<ColorCanal, HexaCanalColor>;
Ici, on définit une structure qui a en clé
ColorCanal
et, pour chacun des canaux,HexaCanalColor
en valeur.
Ce qui permettra de fabriquer à nouveau la couleur avec :
const hexaFrom = (color: Color): string => `#${color[Red]}${color[Green]}${color[Blue]}`;
Ce qui donne, pour notre couleur #7FFF00
:
expect(
hexaFrom({
[Red]: '7F',
[Green]: 'FF',
[Blue]: '00',
})
).toBe('#7FFF00');
En résumé, nous venons de voir :
- Un rappel avec deux utilisations des Union Type sur
ColorCanal
etHexaDigit
; - La notion de Template Literal et de ses limites avec
HexaCanalColor
etHexaColor
; - Une utilisation des Record<Keys, Type> avec de l'exhaustivité sur les
Keys
et lesValues
avecColor
.
Et peut-être aussi quelques notions sur la représentation des couleurs !