Such as:
let str: ByteString = "01afe3"; // valid
let str1: ByteString = "0a1" // invalid, hex string length should be even
let str2: ByteString = "hello" //invalid, only hex allow
The value can be any string that is a valid hex.
I have tried the code below:
type HexChar = '0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
type HexColor = `#${HexChar}${HexChar}${HexChar}${HexChar}${HexChar}${HexChar}`;
let color: HexColor = '#123456';
But this only works when the value is fixed length.
We want a type that can handle any length, if the string value is valid.
CodePudding user response:
First you need to define a generic HexType
which is a conditional type and uses recursive logic:
type HexChar = '0' | '1' | '2' | '3' | '4'
| '5' | '6'| '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
| 'a' | 'b' | 'c' | 'd' | 'e' | 'f';
type HexType<T extends string> = T extends `${infer R1}${infer R2}`
? R1 extends HexChar
? `${R1}${HexType<R2>}`
: never
: `${T}`;
Then create a helper function which gets any value but if the value type is not
HexType
the argument type will be never
so the function gives you an error.
const MyHexTypeFunction = <T extends string>(value: HexType<T>) => value;
For example :
const value = MyHexTypeFunction("qxb12"); //gives never type and also gives error
const value2 = MyHexTypeFunction("AB234"); //value2 type is "AB234"
If you want the Hex string to be even length you can use another generic type and helper function like so:
type HasEvenLegth<T extends string> =
T extends `${infer R1}${infer R2}${infer R3}`
? R3 extends ""
? T
: `${R1}${R2}${HasEvenLegth<R3>}`
: T extends ""
? ""
: never;
const HasEvenLegthFunction = <T extends string>(value: HasEvenLegth<T>) => value;
For example :
const value3 = HasEvenLegthFunction(MyHexTypeFunction("E23a318"));
//gives never type and also gives error because it has odd length
const value4 = HasEvenLegthFunction(MyHexTypeFunction("EQ"));
//gives never type and also gives error because it has invalid character
const value5 = HasEvenLegthFunction(MyHexTypeFunction("AbbbB234"));
//value5 type is "AbbbB234" it has no error
You can read more about the conditional types here.
CodePudding user response:
Thank you.
All solution I found is below:
type HexChar = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
type HexType<T extends string> =
T extends `${infer R1}${infer R2}${infer R3}`
? R1 extends HexChar
? R2 extends HexChar
? `${R1}${R2}${HexType<R3>}`
: never
: never
: T extends `${infer R1}${infer R2}`
? R1 extends `${HexChar}${HexChar}`
? `${R1}${HexType<R2>}`
: never
: `${T}`;
/**
* Converts a hex literal to string.
* @param {string} hexStr - should be in format of hex literal, i.e. `/^([0-9a-fA-F]{2})*$/`
*/
export function hexToString<T extends string >(hexStr: HexType<T>): string {
return hexStr;
};
hexToString("00aa")
But this requires a helper function hexToString
. I don't want a helper function, I just want a type.