I have encountered duplication in my code where allowed strings are declared twice, once in the type declaration and again in the type guard. How can I refactor my code to eliminate this redundancy?
// inspired by: https://github.com/mattdesl/parse-unit
export type ParsedValue = {
value: number;
unit: Unit;
};
type Unit =
| "ch"
| "ex"
| "em"
| "rem"
| "in"
| "cm"
| "mm"
| "pt"
| "pc"
| "px";
export function parseUnit(str: string | null): ParsedValue | null {
if (!str) {
return null;
}
var value = parseFloat(str);
const match = str.match(/[\d.\-\+]*\s*(.*)/);
const unit = match ? match[1] : "";
if (!isUnit(unit)) {
return null;
}
return { value, unit };
}
export function isUnit(str: string): str is Unit {
return ["ch", "ex", "em", "rem", "in", "cm", "mm", "pt", "pc", "px"].includes(
str
);
}
EDIT:
After receiving some suggestions, here is the updated version of the code. Unfortunately, this version is not functioning properly. I am encountering an error stating
Type 'string' is not assignable to type '"ch" | "ex" | "em" | "rem" | "in" | "cm" | "mm" | "pt" | "pc" | "px"'.
// inspired by: https://github.com/mattdesl/parse-unit
export type ParsedValue = {
value: number;
unit: Unit;
};
const units = [
"ch",
"ex",
"em",
"rem",
"in",
"cm",
"mm",
"pt",
"pc",
"px",
] as const;
type Unit = typeof units[number];
export function parseUnit(str: string): ParsedValue | null {
if (!str) {
return null;
}
var value = parseFloat(str);
const match = str.match(/[\d.\-\+]*\s*(.*)/);
const unit = match ? match[1] : "";
if (!isUnit(str)) {
return null;
}
return { value, unit };
}
export function isUnit(str: string): str is Unit {
return ((units as unknown) as Array<string>).includes(str);
}