#Prevent `boolean` From Expanding to `true | false` In Conditional Typing

47 messages ยท Page 1 of 1 (latest)

dreamy rain
#

Hi everyone! I've been working on a cleaner replacement for toZod, and was implementing union types, and came across boolean expanding to true | false. Does anyone know of a way to prevent this behavior? Here is a playground link that demonstrates this behavior. Hover over the Test type at the very bottom to see what I mean.

#

Also - with multiple (more than two) union types, I get nested unions. Is this possible to avoid?

#

this correctly extracts the type, but then it gets resolved as an object. T extends [infer U] ? z.ZodArray<ToZod<U>>

tired zephyrBOT
#
d.n_n.b#0

Preview:ts ... type Test = ToZod<number | boolean | string> // ^?

deft lance
#

the issue you're running into is this:

#

!hb dist

tired zephyrBOT
deft lance
#

which is triggered any time you do T extends, where the left side of the extends is a "bare type parameter"

dreamy rain
#

ah, i'll look at the docs. ty

frigid sleet
#

[T] extends [U] is often used as a substitute for T extends U that doesn't trigger distribution

#

(Ah, right that is actually mentioned in the docs)

dreamy rain
#

yep!

dreamy rain
deft lance
#

probably

type IsArray<T extends readonly unknown[]> = IsEqual<T, T[number][]>
#

T extends [infer First, ...infer Rest] works most of the time too

tired zephyrBOT
deft lance
#

!ts

tired zephyrBOT
#
type IsArray<T> = T extends [infer First, ...infer Rest] ? [First, Rest] : never;

type A = IsArray<[...'a'[], 'b']>
//   ^? - type A = never```
deft lance
#

although it's not entirely foolproof

#

that said, if your tuple has a spread in it then it's probably impossible to do type manipulation on it

#

(well, i supposed you can use a mapped type. but what you can do with that is somewhat limited)

#

on the other hand it's not like zod can represent tuples with spreads anyway, right?

dreamy rain
#

I feel so bad for needing to be spoonfed, but I literally have zero idea what i'm doing when it comes to arrays and types ๐Ÿ˜ญ

#

wait a minute. [T] is saying Array<T> with a size of one. That's why.

#

because if I input string[], it's like saying [string[]] extends [string[], ...[]]

cosmic mortar
dreamy rain
#

I don't think it's possible to dertermine between ['foo', 'bar'] and string[]

dreamy rain
cosmic mortar
#

That strategy can also be used in some of these other areas e.g. type IsBooleanLiteral<T> = boolean extends T ? false : true

dreamy rain
#

oh your right

#

i just did it the hard way I guess

cosmic mortar
#

IsUndefined should really just be T extends undefined if you're worried about any and never the best strategy is to check for those first so you can eliminate them rather then dealing with them in each case like this

dreamy rain
#

which is how I learn, so maybe i'm not doing too bad after all

dreamy rain
#

or maybe i could make a try for that

cosmic mortar
dreamy rain
#

ohh I see

#

mb

cosmic mortar
#

any and never are always a thorn in your side if you have to deal with this kind of thing best to do it up front so you don't have to worry about so many edge cases ๐Ÿ™‚

dreamy rain
#

yeah :)

#

I still can't wrap my head around mapping the types in an array

#

All I need to do is 'transform' (or map) each type to a new type

#

but that seems impossible atm

dreamy rain
#

it was this easy ๐Ÿ˜ญ

type ArrayToZod<T> = { [P in keyof T]: ToZod<T[P]> }```