Implementa `Subtract<A, B>` que devuelva `A − B` como literal numérico. Cuando `B` es mayor que `A`, la respuesta es `never` — no existen longitudes de tupla negativas.
01
Intenta el puzle tú mismo
Par 5
Puzle
type-level-subtract.ts
type BuildTuple<N extendsnumber, Acc extendsunknown[] = []> =
Acc['length'] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>
type Subtract<A extendsnumber, B extendsnumber> = ???
Intento 1 de 5Aún sin comprobar
Sustituye ??? — tu solución se comprueba con los casos de abajo. Tab indenta; pulsa Escape y luego Tab para sacar el foco.
Comprobaciones
4
Subtract<5, 3>—
→ 2
Subtract<3, 3>—
→ 0
Subtract<10, 4>—
→ 6
Subtract<2, 5>—
→ never
Cómo se juzga una comprobación Igualdad exacta de tipos, no asignabilidad — una intersección no es lo mismo que el objeto aplanado.
Cómo le fue a todo el mundo
Menos de 5 personas han resuelto este puzle hasta ahora. La distribución aparece cuando la muestra sea lo bastante grande como para significar algo.
type Subtract<A extendsnumber, B extendsnumber> =
BuildTuple<A> extends [...BuildTuple<B>, ...infer Rest] ? Rest['length'] : never
El error más común
type Subtract<A extendsnumber, B extendsnumber> =
[...BuildTuple<A>, ...BuildTuple<B>]['length']
Eso es la suma con otro nombre. Concatenar las dos tuplas solo puede alargarlas; la resta tiene que *desarmar* una tupla, lo que exige emparejar patrones en vez de construir.
Línea por línea
[...BuildTuple<B>, ...infer Rest]
El patrón fija un prefijo de exactamente `B` elementos y deja que `Rest` absorba lo que quede. El emparejamiento solo tiene éxito si el sujeto es al menos así de largo.
: never
Cuando `B > A` no hay forma de alinear el prefijo, el condicional falla y sale `never` — la respuesta honesta para una resta que esta aritmética no puede representar.
Para recordar
Construir tuplas suma; desestructurarlas resta. Toda operación aritmética que TypeScript puede hacer a nivel de tipos es uno de esos dos movimientos disfrazado.