I’m taking type-challenge exercise with the easy part, implement the type version of Unshift.(https://github.com/type-challenges/type-challenges/tree/master/questions/3060-easy-unshift)
Here is my code:
type Unshift<T extends unknown, U> = U extends unknown ? [...U, ...T] : [U, ...T]
the problem is with boolean type:
type Res = Unshift<['1', 2, '3'], boolean> // expected: [boolean,'1',2,'3'] // actual: [false,'1',2,'3'] | [true,'1',2,'3']
I don’t know why is that and how to get expected result.
BTW, I got a pretty similar solution from another answer(Typescript spread operator for type),
type Cons<H, T extends readonly any> = ((h: H, ...t: T) => void) extends ((...r: infer R) => void) ? R : never
is it a trick that should be rote?
The reason you get a union result type is that
boolean is a union (
false) and conditional types distribute over union types (docs). Because of this,
Unshift<['1', 2, '3'], boolean> evaluates to
Unshift<['1', 2, '3'], true> | Unshift<['1', 2, '3'], false>.
You can prevent it from happening by surrounding both sides of the
extends condition with square brackets:
type Unshift<T extends unknown, U> = [U] extends [unknown] ? [...U, ...T] : [U, ...T] type Res = Unshift<['1', 2, '3'], boolean> // type Res = [boolean, "1", 2, "3"]
Answered By – Oblosys
Answer Checked By – Cary Denson (BugsFixing Admin)