Home > Blockchain >  How to define a typescript type which can check that the string value is a valid hex string?
How to define a typescript type which can check that the string value is a valid hex string?

Time:12-13

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.

  • Related