#30575β€’Hard

BitwiseXOR

XOR two binary string literals of different lengths. Bitwise ops align at the right end, the one end template literal inference cannot reach, so you reverse first.

XOR two binary strings with no ^ operator in reach, just string types.

The inputs to BitwiseXOR<S1, S2> are two binary string literal types, and the output is a binary string representing their bitwise XOR. What earns this the hard label: the inputs can have different lengths, and bitwise operations align numbers at the right end, the one end template literal inference can't reach directly.

For example:

BitwiseXOR<'0','1'> // expect '1'
BitwiseXOR<'1','1'> // expect '0'
BitwiseXOR<'10','1'>  // expect '11'

Solving it teaches a classic maneuver for type-level string algorithms: when you need to work from the wrong end of a string, reverse it first.

Challenge Instructions: BitwiseXOR

Hard

Implement BitwiseXOR<S1,S2> which takes two binary string literal type and returns a binary string that represents the bitwise XOR of S1 and S2

For example:

BitwiseXOR<'0','1'> // expect '1'
BitwiseXOR<'1','1'> // expect '0'
BitwiseXOR<'10','1'>  // expect '11'

View on GitHub: https://tsch.js.org/30575

Change the following code to make the test cases pass (no type check errors).

πŸ‘‹ Lifetime-License is leaving on August 10, 2026

Get it now for $29

One-time payment. Lifetime access to all pro challenges.

Loading...

Detailed Explanation

Three small helpers make up the solution:

type Xor<A extends string, B extends string> = A extends B ? '0' : '1'
 
type Reverse<S extends string> = S extends `${infer First}${infer Rest}`
  ? `${Reverse<Rest>}${First}`
  : ''
 
type XorReversed<
  S1 extends string,
  S2 extends string,
> = S1 extends `${infer B1}${infer R1}`
  ? S2 extends `${infer B2}${infer R2}`
    ? `${Xor<B1, B2>}${XorReversed<R1, R2>}`
    : S1
  : S2
 
type BitwiseXOR<S1 extends string, S2 extends string> = Reverse<
  XorReversed<Reverse<S1>, Reverse<S2>>
>

Each does one job. Here is why the problem decomposes this way.

Why reverse at all?

Template literal inference can only peel characters off the front of a string: in `${infer First}${infer Rest}`, when one infer is immediately followed by another, the first matches exactly one character and the second takes the remainder. There is no mirror-image pattern for grabbing the last character.

But XOR aligns numbers at their least significant bit, the rightmost one. '10' ^ '1' means 10 ^ 01, not 10 ^ 10. If you zipped the strings from the left, the '1' would line up with the wrong column.

The fix is the sandwich in BitwiseXOR: reverse both inputs so the least significant bits come first, zip them left to right, then reverse the result back. Reverse itself is a compact recursion: take the first character, reverse the rest, and glue the character on the end:

[object Object]

XOR for a single bit

Xor<A, B> rests on one observation: for two bits, XOR just asks whether they differ. A extends B is true exactly when the two literal types are identical ('0'/'0' or '1'/'1'), so equal bits yield '0' and unequal bits yield '1'. No truth table needed. (This only works as an equality test because both sides are always a single bit literal; extends against a union or a wider type is a subtype check, not equality.)

Zipping two strings of different lengths

XorReversed walks both (already reversed) strings in lockstep, one character per recursion step:

Tracing BitwiseXOR<'101', '11'>:

// Reverse<'101'> = '101',  Reverse<'11'> = '11'
// step 1: Xor<'1', '1'> = '0', recurse on '01' and '1'
// step 2: Xor<'0', '1'> = '1', recurse on '1' and ''
// step 3: S2 is empty β†’ return '1'
// zipped result: '011' β†’ Reverse β†’ '110'

Which matches 5 ^ 3 = 6 in decimal.

Edge cases the tests cover

The reverse-process-reverse pattern is the real takeaway: any time a string algorithm naturally runs right to left, arithmetic carries for instance, reversing first turns it into a left-to-right recursion TypeScript is happy to run.

This challenge is originally from here.

Share this challenge

Learn the Concepts