#How do I make it so a property determines the type of another property (& why doesnt my way work)

27 messages · Page 1 of 1 (latest)

ocean sentinel
#

I'm trying to make it so the property type determines the type of data

type x = (
  {'type': 'user', data: UserData} |
  {'type': 'post', data: PostData}
)

if (xObject.type === 'user') {
  // The type of data should now be UserData. Instead it's (UserData | PostData).
}

How do I make this work

summer sleet
#

how are UserData and PostData defined?

#

oh wait nevermind, i misread. that's probably not important

#

looks right to me?

zinc flickerBOT
#
type UserData = 'UserData'
type PostData = 'PostData'

type x = (
  {'type': 'user', data: UserData} |
  {'type': 'post', data: PostData}
)

declare const xObject: x
if (xObject.type === 'user') {
  xObject.data
//        ^? - (property) data: "UserData"
}
ocean sentinel
summer sleet
#

i gotta run, but i can check back later

ocean sentinel
#

🤔

zinc flickerBOT
#
scrimbo.bimbo#0

Preview:```ts
type UserData = {username: string; banner: string}
type PostData = {username: string; url: string}
type X =
| {type: "user"; data: UserData}
| {type: "post"; data: PostData}

const getStuff = (): X => {
return {
type: "user",
data: {
username: "s",
banner: "/fasduhf/fhsduiahf",
...```

ocean sentinel
#

It works on the playground, but not in my env?

ocean sentinel
#

I've tried:

  • Switching from vs-codium to vs-code
  • Updating typescript
  • Restarting Typescript servers
west shuttle
ocean sentinel
#

Turns out it wasn't vscode's fault, the version I made for you guys must've been too simplified. Here's a playground that has the error
@summer sleet @west shuttle

zinc flickerBOT
#
scrimbo.bimbo#0

Preview:```ts
type userPreload = {
username: string
banner: string
}
type postPreload = {
username: string
url: string
}

const getData = async (): Promise<
| {type: "user"; preload: userPreload}
| {type: "post"; preload: postPreload}

=> {
return {
type: "user",
...```

west shuttle
#

type is decoupled from the rest of the object there from the destructuring

ocean sentinel
#

?

zinc flickerBOT
#
that_guy977#0

Preview:```ts
...
const head = async () => {
// let {type, preload} = await getData()
let data = await getData()

// switch (type) {
switch (data.type) {
case "user": {
// preload.banner
data.preload.banner
}
}
// if (type === 'user') {
if (data.type === "user") {
// preload.banner
data.preload.banner
}
return
}```

west shuttle
#

the destructuring makes narrowing type unable to narrow the other properties

ocean sentinel
#

OOOoooooohhhhh
That's weird

#

alright, thank you for your patients

west shuttle
#

oh actually

west shuttle
#

if you use const, the destructuring works fine

#

(i think let actually causes the decoupling? haven't worked with ts for a while, kinda fuzzy, sorry)

#

as a rule of thumb (for js), use const wherever you can.
ts can also give better types/analysis for consts than lets

summer sleet
#

yeah seems like let destructuring doesn't keep the properties correlated the way const destructuring does. interesting