Búsqueda de sitios web

javascript - Comprobación de argumentos en Typescript contra un tipo unión


Quiero comprobar si una cadena tiene un prefijo que coincida con un tipo unión, por ejemplo:

type Prefix = "ABC" | "DEF" | "GHI" ...;
const hasPrefix = (str: string): boolean => {
   // I want to check the first 3 characters of the string
   // And see if it matches any of the Prefix
   // Something like
   //  if (str.substr(0, 3) === Prefix)
}

Respuesta #1

En la versión actual de TypeScript no se puede diseccionar un tipo unión. Para tu problema recomendaría un enfoque usando enums de la siguiente manera:

enum Prefixes {
    "ABC",
    "DEF",
    "GHI"
}

const hasPrefix = (str: string): boolean => Prefixes[str.substr(0, 3) as any] !== "undefined";

console.log(hasPrefix("123")); // false
console.log(hasPrefix("ABC")); // true
console.log(hasPrefix("DEF")); // true
console.log(hasPrefix("GHI")); // true
console.log(hasPrefix("GHII"));// true

const data = "ABC123";         // ABC123

console.log(hasPrefix(data));  // true
console.log(data);             // still ABC123

Aquí hay un playground de TypeScript del código anterior.

A juzgar por tu pregunta, parece que estás interesado en una forma dinámica de comprobar los prefijos (¿los caracteres ... implican esto?). Esto me hizo pensar y se me ocurrió una solución usando un tipo de dato Set. Considera este ejemplo:

// Set data type ensures only uniques
type Prefix = string;
const prefixes: Set<Prefix> = new Set();

prefixes.add("ABC");
prefixes.add("ABC");
prefixes.add("DEF");
prefixes.add("GHI");

// No doubles here so we're good (note the double added ABC string)
console.log(prefixes);

// the typeguard
const hasPrefix = (str: any): str is Prefix => typeof str === "string" ? prefixes.has(str.substr(0, 3)): false;

console.log(hasPrefix(100));   // false
console.log(hasPrefix(0));     // false
console.log(hasPrefix(false)); // false
console.log(hasPrefix(true));  // false
console.log(hasPrefix(""));    // false
console.log(hasPrefix("123")); // false
console.log(hasPrefix("ABC")); // true
console.log(hasPrefix("DEF")); // true
console.log(hasPrefix("GHI")); // true
console.log(hasPrefix("GHII"));// true

const data = "ABC123";         // ABC123

if (hasPrefix(data)) {
    console.log(hasPrefix(data));  // true
    console.log(data);             // still ABC123
}

Aquí está el área de juegos para ese código.

Respuesta #2

Creo que no es posible en este momento solo con tipos incorporados de Typescript. https://github.com/Microsoft/TypeScript/issues/6579 y como referencia a propuestas: ¿Cómo definir un tipo de cadena que coincida con una expresión regular en Typescript?

Artículos relacionados