Un builder tipado en TypeScript
El genérico rastrea qué campos se han provisto hasta el momento.
interface Query {
table: string;
where?: string;
limit?: number;
}
class QueryBuilder<Have extends keyof Query = never> {
private parts: Partial<Query> = {};
from(table: string): QueryBuilder<Have | "table"> {
this.parts.table = table;
return this as QueryBuilder<Have | "table">;
}
where(clause: string): QueryBuilder<Have | "where"> {
this.parts.where = clause;
return this as QueryBuilder<Have | "where">;
}
build(this: QueryBuilder<"table" | Have>): string {
const { table, where, limit } = this.parts;
return [`SELECT * FROM ${table}`, where && `WHERE ${where}`,
limit && `LIMIT ${limit}`].filter(Boolean).join(" ");
}
}
console.log(new QueryBuilder().from("runs").where("tpm > 90").build());
// new QueryBuilder().where("x").build(); // error: table nunca se definió
Cómo funciona
- Cada setter ensancha el conjunto de claves acumulado.
buildsolo pasa el chequeo de tipos cuando están las claves requeridas.- El compilador impone el orden que de verdad necesitas.
Palabras clave y builtins usados aquí
BooleanPartialQueryBuilderasclassconstextendsfrominterfacenumberprivatereturnstringthis
El intento, en números
- Líneas
- 28
- Caracteres a escribir
- 777
- Tokens
- 196
- Ritmo de tres estrellas
- 110 tpm
Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 107 segundos.
Paso 1 de 5 en Construcción e inyección; paso 9 de 19 en Clases y patrones.