#Type narrowing a variable property name

1 messages · Page 1 of 1 (latest)

bold fox
#

Hey people,

Given the following two types:

interface A {
    [id: string]: number;
}

interface B {
    detail: string;
}


I want to be able to narrow down a type for a variable that is abc: A | B. For example in a function like this:

const fn = (v: A | B) => {
    if (!("detail" in v)) {
        // v is type A here
    }
}

I can type narrow to get all instances where v is A. But I can't figure out if it's possible to type narrow to get v: B considering detail is a subset of [id: string]?

hexed bloomBOT
#
ThePageMan#2216

Preview:```ts
interface A {
[id: string]: number
}

interface B {
detail: string
}

const fn = (v: A | B) => {
if (!("detail" in v)) {
// v is type A here
v
}
}```

final compass
#

well, B is a subtype of A

#

so you kinda can't

#

if it's B, it's also a valid A

#

ah wait misread

#

you could use "detail" in v && typeof v.detail === "string"

#

doesn't look like ts narrows based on that though, so you'd have to make it a typeguard

bold fox
#

Mmm, doesn't seem to type narrow it in the sandbox

final compass
bold fox
#

Logically yeah, but unfortunately I don't know how to tell that to TS 😛

hexed bloomBOT
bold fox
#

Ah interesting...

#

How is this not bad practice?

final compass
#

why do you think it would be bad practice?

bold fox
#

It seems similar to type assertions !. User intervention. Although seeing the example, it is being used in a TS helper function which could make it different. Lemme try

#

Oh my goodness, it works:

const vIsB = (v: A | B): v is B => {
    return typeof v.detail === "string";
}

const fn = (v: A | B) => {
    if (vIsB(v)) {
        // v is type A here
        v
    }
}
final compass
#

it's not just saying that v is definitely T here, it's saying that if [runtime check] passes, then and only then is v a T

#

although yeah it is up to the developer to make proper guards

#

but ts can't narrow everything so it kinda makes sense

bold fox
#

Yeah it's pretty wild, I can't think of another instance where I've had to make runtime logic for TS

#

Although it's not quite "runtime logic for TS"

#

Wild.

#

Don't even know how to describe it

final compass
#

ive heard some libraries like zod can generate those runtime checks to make them definitely valid

bold fox
#

Thanks for teaching me something new today

final compass
#

sounds like you might like that

bold fox
#

!resolved