Z
Zod9mo ago
janglad

janglad - I may be missinng something here or m...

I may be missinng something here or maybe it's a TS limitation but I would expect the last line to give a TS error saying that type can never be "LISTING" (since owner.type is company). Why is this not happening?
import z from "zod"

const union = z.union([
z.object({
type: z.literal("LEGAL"),
owner: z.object({
type: z.literal("COMPANY")
})
}),
z.object({
type: z.literal("LISTING"),
owner: z.object({
type: z.literal("PRIVATE")
})
})
])

const test : z.output<typeof union> = {} as any;

// TS Error
if (test.type === "LISTING") test.owner.type === "COMPANY"

// TS Error
const test2 : z.output<typeof union> = {
type: "LISTING",
owner:{
type: "COMPANY"
}
}

// Valid
if (test.owner.type === "COMPANY") test.type === "LISTING"
import z from "zod"

const union = z.union([
z.object({
type: z.literal("LEGAL"),
owner: z.object({
type: z.literal("COMPANY")
})
}),
z.object({
type: z.literal("LISTING"),
owner: z.object({
type: z.literal("PRIVATE")
})
})
])

const test : z.output<typeof union> = {} as any;

// TS Error
if (test.type === "LISTING") test.owner.type === "COMPANY"

// TS Error
const test2 : z.output<typeof union> = {
type: "LISTING",
owner:{
type: "COMPANY"
}
}

// Valid
if (test.owner.type === "COMPANY") test.type === "LISTING"
Solution:
Yeah, this is a typescript thing: an object's discriminant needs to be at the base level of that object.
Jump to solution
3 Replies
Solution
Scott Trinh
Scott Trinh9mo ago
Yeah, this is a typescript thing: an object's discriminant needs to be at the base level of that object.
janglad
janglad9mo ago
I figured, thanks!
Scott Trinh
Scott Trinh9mo ago
In other words, that first check only narrows the test.owner object, not the test object.
Want results from more Discord servers?
Add your server